home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / gpp-1_42.lha / g++-1.42.0 / cplus-parse.y < prev    next >
Text File  |  1991-10-19  |  90KB  |  3,159 lines

  1. /* YACC parser for C++ syntax.
  2.    Copyright (C) 1988, 1989 Free Software Foundation, Inc.
  3.    Hacked by Michael Tiemann (tiemann@mcc.com)
  4.  
  5. This file is part of GNU CC.
  6.  
  7. GNU CC is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 1, or (at your option)
  10. any later version.
  11.  
  12. GNU CC is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with GNU CC; see the file COPYING.  If not, write to
  19. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21.  
  22. /* This grammar is based on the GNU CC grammar.  */
  23.  
  24. /* Also note: this version contains experimental exception
  25.    handling features.  They could break, change, disappear,
  26.    or otherwise exhibit volatile behavior.  Don't depend on
  27.    me (Michael Tiemann) to protect you from any negative impact
  28.    this may have on your professional, personal, or spiritual life.  */
  29.  
  30. %{
  31. #include "config.h"
  32. #include "tree.h"
  33. #include "input.h"
  34. #include "cplus-parse.h"
  35. #include "cplus-tree.h"
  36. #include "assert.h"
  37.  
  38. /* C++ extensions */
  39. extern tree ridpointers[];    /* need this up here */
  40. extern tree void_list_node;
  41.  
  42. #include <stdio.h>
  43. #include <errno.h>
  44.  
  45. #ifndef errno
  46. extern int errno;
  47. #endif
  48.  
  49. extern int end_of_file;
  50.  
  51. void yyerror ();
  52.  
  53. /* Contains error message to give if user tries to declare
  54.    a variable where one does not belong.  */
  55. static char *stmt_decl_msg = 0;
  56.  
  57. #ifndef YYDEBUG
  58. /* Cause the `yydebug' variable to be defined.  */
  59. int yydebug;
  60. #endif
  61.  
  62. /* Cons up an empty parameter list.  */
  63. #ifdef __GNU__
  64. __inline
  65. #endif
  66. static tree
  67. empty_parms ()
  68. {
  69.   tree parms;
  70.  
  71.   if (strict_prototype)
  72.     parms = void_list_node;
  73.   else
  74.     parms = NULL_TREE;
  75.   return parms;
  76. }
  77.  
  78. void yyhook ();
  79. %}
  80.  
  81. %start program
  82.  
  83. %union {long itype; tree ttype; enum tree_code code; }
  84.  
  85. /* All identifiers that are not reserved words
  86.    and are not declared typedefs in the current block */
  87. %token IDENTIFIER
  88.  
  89. /* All identifiers that are declared typedefs in the current block.
  90.    In some contexts, they are treated just like IDENTIFIER,
  91.    but they can also serve as typespecs in declarations.  */
  92. %token TYPENAME
  93.  
  94. /* Reserved words that specify storage class.
  95.    yylval contains an IDENTIFIER_NODE which indicates which one.  */
  96. %token SCSPEC
  97.  
  98. /* Reserved words that specify type.
  99.    yylval contains an IDENTIFIER_NODE which indicates which one.  */
  100. %token TYPESPEC
  101.  
  102. /* Reserved words that qualify type: "const" or "volatile".
  103.    yylval contains an IDENTIFIER_NODE which indicates which one.  */
  104. %token TYPE_QUAL
  105.  
  106. /* Character or numeric constants.
  107.    yylval is the node for the constant.  */
  108. %token CONSTANT
  109.  
  110. /* String constants in raw form.
  111.    yylval is a STRING_CST node.  */
  112. %token STRING
  113.  
  114. /* "...", used for functions with variable arglists.  */
  115. %token ELLIPSIS
  116.  
  117. /* the reserved words */
  118. %token SIZEOF ENUM /* STRUCT UNION */ IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
  119. %token BREAK CONTINUE RETURN GOTO ASM TYPEOF ALIGNOF
  120. %token ATTRIBUTE
  121.  
  122. /* the reserved words... C++ extensions */
  123. %token <ttype> AGGR
  124. %token DELETE NEW OVERLOAD PRIVATE PUBLIC PROTECTED THIS OPERATOR
  125. %token DYNAMIC POINTSAT_LEFT_RIGHT LEFT_RIGHT
  126. %token <itype> SCOPE
  127.  
  128. /* Define the operator tokens and their precedences.
  129.    The value is an integer because, if used, it is the tree code
  130.    to use in the expression made from the operator.  */
  131.  
  132. %left EMPTY            /* used to resolve s/r with epsilon */
  133.  
  134. /* Add precedence rules to solve dangling else s/r conflict */
  135. %nonassoc IF
  136. %nonassoc ELSE
  137.  
  138. %left IDENTIFIER TYPENAME TYPENAME_COLON SCSPEC TYPESPEC TYPE_QUAL ENUM AGGR
  139.  
  140. %left '{' ','
  141.  
  142. %right <code> ASSIGN '='
  143. %right <code> '?' ':' RANGE
  144. %left <code> OROR
  145. %left <code> ANDAND
  146. %left <code> '|'
  147. %left <code> '^'
  148. %left <code> '&'
  149. %left <code> MIN_MAX
  150. %left <code> EQCOMPARE
  151. %left <code> ARITHCOMPARE
  152. %left <code> LSHIFT RSHIFT
  153. %left <code> '+' '-'
  154. %left <code> '*' '/' '%'
  155. %right <code> UNARY PLUSPLUS MINUSMINUS
  156. %left HYPERUNARY
  157. %left <ttype> PAREN_STAR_PAREN PAREN_X_SCOPE_STAR_PAREN PAREN_X_SCOPE_REF_PAREN LEFT_RIGHT
  158. %left <code> POINTSAT '.' '(' '['
  159.  
  160. %right SCOPE            /* C++ extension */
  161. %nonassoc NEW DELETE RAISE RAISES RERAISE TRY EXCEPT CATCH
  162. %right DYNAMIC
  163.  
  164. %type <code> unop
  165.  
  166. %type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist /* exprlist */
  167. %type <ttype> expr_no_commas cast_expr unary_expr primary string STRING
  168. %type <ttype> typed_declspecs reserved_declspecs
  169. %type <ttype> typed_typespecs reserved_typespecquals
  170. %type <ttype> declmods typespec typespecqual_reserved
  171. %type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual
  172. %type <itype> initdecls notype_initdecls initdcl    /* C++ modification */
  173. %type <ttype> init initlist maybeasm
  174. %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
  175. %type <ttype> maybe_attribute attribute_list attrib
  176.  
  177. %type <ttype> compstmt except_stmts
  178.  
  179. %type <ttype> declarator notype_declarator after_type_declarator
  180.  
  181. %type <ttype> structsp opt.component_decl_list component_decl_list component_decl components component_declarator
  182. %type <ttype> enumlist enumerator
  183. %type <ttype> typename absdcl absdcl1 type_quals
  184. %type <ttype> xexpr see_typename parmlist parms parm bad_parm
  185.  
  186. /* C++ extensions */
  187. %token <ttype> TYPENAME_COLON TYPENAME_SCOPE TYPENAME_ELLIPSIS
  188. %token <ttype> PRE_PARSED_FUNCTION_DECL EXTERN_LANG_STRING ALL
  189. %type <ttype> fn.def2 dummy_decl x_typespec return_id
  190. %type <ttype> class_head opt.init base_class_list base_class_visibility_list
  191. %type <ttype> after_type_declarator_no_typename
  192. %type <ttype> maybe_raises raise_identifier raise_identifiers
  193. %type <ttype> component_declarator0 scoped_identifier
  194. %type <ttype> forhead.1 identifier_or_opname operator_name
  195. %type <ttype> new delete object primary_no_id aggr nonmomentary_expr
  196. %type <itype> LC forhead.2 initdcl0 notype_initdcl0 wrapper member_init_list
  197. %type <itype> .scope try
  198.  
  199. %{
  200. /* the declaration found for the last IDENTIFIER token read in.
  201.    yylex must look this up to detect typedefs, which get token type TYPENAME,
  202.    so it is left around in case the identifier is not a typedef but is
  203.    used in a context which makes it a reference to a variable.  */
  204. tree lastiddecl;
  205.  
  206. tree make_pointer_declarator (), make_reference_declarator ();
  207.  
  208. tree combine_strings ();
  209. void reinit_parse_for_function ();
  210. void reinit_parse_for_method ();
  211.  
  212. /* List of types and structure classes of the current declaration.  */
  213. tree current_declspecs;
  214.  
  215. int undeclared_variable_notice;    /* 1 if we explained undeclared var errors.  */
  216.  
  217. int yylex ();
  218. extern FILE *finput;
  219. %}
  220.  
  221. %%
  222. program: .program /* empty */
  223.     | .program extdefs
  224.         { finish_file (); }
  225.     ;
  226.  
  227. .program: /* empty */
  228.         {
  229.         }
  230.  
  231. /* the reason for the strange actions in this rule
  232.  is so that notype_initdecls when reached via datadef
  233.  can find a valid list of type and sc specs in $0. */
  234.  
  235. extdefs:
  236.       {$<ttype>$ = NULL_TREE; } extdef
  237.     | extdefs {$<ttype>$ = NULL_TREE; } extdef
  238.     ;
  239.  
  240. extdef:
  241.       fndef
  242.         { if (pending_inlines) do_pending_inlines (); }
  243.     | datadef
  244.         { if (pending_inlines) do_pending_inlines (); }
  245.     | overloaddef
  246.     | ASM '(' string ')' ';'
  247.         { if (pedantic)
  248.             warning ("ANSI C forbids use of `asm' keyword");
  249.           if (TREE_CHAIN ($3)) $3 = combine_strings ($3);
  250.           assemble_asm ($3); }
  251.     | extern_lang_string '{' extdefs '}'
  252.         { pop_lang_context (); }
  253.     | extern_lang_string '{' '}'
  254.         { pop_lang_context (); }
  255.     | extern_lang_string fndef
  256.         { if (pending_inlines) do_pending_inlines ();
  257.           pop_lang_context (); }
  258.     | extern_lang_string datadef
  259.         { if (pending_inlines) do_pending_inlines ();
  260.           pop_lang_context (); }
  261.     ;
  262.  
  263. extern_lang_string:
  264.       EXTERN_LANG_STRING
  265.         { push_lang_context ($1); }
  266.     ;
  267.  
  268. overloaddef:
  269.       OVERLOAD ov_identifiers ';'
  270.  
  271. ov_identifiers: IDENTIFIER
  272.         { declare_overloaded ($1); }
  273.     | ov_identifiers ',' IDENTIFIER
  274.         { declare_overloaded ($3); }
  275.     ;
  276.       
  277. dummy_decl: /* empty */
  278.         { $$ = NULL_TREE; }
  279.     ;
  280.  
  281. datadef:
  282.       dummy_decl notype_initdecls ';'
  283.         { if (pedantic)
  284.             error ("ANSI C forbids data definition lacking type or storage class");
  285.             else if (! flag_traditional)
  286.               warning ("data definition lacks type or storage class"); }
  287.     | declmods notype_initdecls ';'
  288.         {}
  289.     /* Normal case to make fast: "int i;".  */
  290.     | declmods declarator ';'
  291.         { tree d;
  292.           d = start_decl ($2, $1, 0, NULL_TREE);
  293.           finish_decl (d, NULL_TREE, NULL_TREE);
  294.         }
  295.     | typed_declspecs initdecls ';'
  296.         {
  297.           end_exception_decls ();
  298.           note_got_semicolon ($1);
  299.         }
  300.     /* Normal case: make this fast.  */
  301.     | typed_declspecs declarator ';'
  302.         { tree d;
  303.           d = start_decl ($2, $1, 0, NULL_TREE);
  304.           finish_decl (d, NULL_TREE, NULL_TREE);
  305.           end_exception_decls ();
  306.           note_got_semicolon ($1);
  307.         }
  308.         | declmods ';'
  309.       { error ("empty declaration"); }
  310.     | typed_declspecs ';'
  311.       {
  312.         shadow_tag ($1);
  313.         note_got_semicolon ($1);
  314.       }
  315.     | error ';'
  316.     | error '}'
  317.     | ';'
  318.     ;
  319.  
  320. fndef:
  321.       fn.def1 base_init compstmt_or_error
  322.         {
  323.           finish_function (lineno, 1);
  324.           /* finish_function performs these three statements:
  325.  
  326.              expand_end_bindings (getdecls (), 1, 0);
  327.              poplevel (1, 1, 0);
  328.  
  329.              expand_end_bindings (0, 0, 0);
  330.              poplevel (0, 0, 1);
  331.              */
  332.         }
  333.     | fn.def1 return_init base_init compstmt_or_error
  334.         {
  335.           finish_function (lineno, 1);
  336.           /* finish_function performs these three statements:
  337.  
  338.              expand_end_bindings (getdecls (), 1, 0);
  339.              poplevel (1, 1, 0);
  340.  
  341.              expand_end_bindings (0, 0, 0);
  342.              poplevel (0, 0, 1);
  343.              */
  344.         }
  345.     | fn.def1 nodecls compstmt_or_error
  346.         { finish_function (lineno, 0); }
  347.     | fn.def1 return_init ';' nodecls compstmt_or_error
  348.         { finish_function (lineno, 0); }
  349.     | fn.def1 return_init nodecls compstmt_or_error
  350.         { finish_function (lineno, 0); }
  351.     | typed_declspecs declarator error
  352.         {}
  353.     | declmods notype_declarator error
  354.         {}
  355.     | dummy_decl notype_declarator error
  356.         {}
  357.     ;
  358.  
  359. fn.def1:
  360.       typed_declspecs declarator maybe_raises
  361.         { if (! start_function ($1, $2, $3, 0))
  362.             YYERROR;
  363.           reinit_parse_for_function (); }
  364.     | declmods notype_declarator maybe_raises
  365.         { if (! start_function ($1, $2, $3, 0))
  366.             YYERROR;
  367.           reinit_parse_for_function (); }
  368.     | dummy_decl notype_declarator maybe_raises
  369.         { if (! start_function (NULL_TREE, $2, $3, 0))
  370.             YYERROR;
  371.           reinit_parse_for_function (); }
  372.     | dummy_decl TYPENAME '(' parmlist ')' type_quals maybe_raises
  373.         { if (! start_function (NULL_TREE, build_parse_node (CALL_EXPR, $2, $4, $6), $7, 0))
  374.             YYERROR;
  375.           reinit_parse_for_function (); }
  376.     | dummy_decl TYPENAME LEFT_RIGHT type_quals maybe_raises
  377.         { if (! start_function (NULL_TREE, build_parse_node (CALL_EXPR, $2, empty_parms (), $4), $5, 0))
  378.             YYERROR;
  379.           reinit_parse_for_function (); }
  380.     | PRE_PARSED_FUNCTION_DECL
  381.         { start_function (NULL_TREE, $1, NULL_TREE, 1);
  382.           reinit_parse_for_function (); }
  383.     ;
  384.  
  385. /* more C++ complexity */
  386. fn.def2:
  387.       typed_declspecs '(' parmlist ')' type_quals maybe_raises
  388.         {
  389.           tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($1), $3, $5);
  390.           $$ = start_method (TREE_CHAIN ($1), decl, $6);
  391.           if (! $$)
  392.             YYERROR;
  393.           if (yychar == YYEMPTY)
  394.             yychar = YYLEX;
  395.           reinit_parse_for_method (yychar, $$); }
  396.     | typed_declspecs LEFT_RIGHT type_quals maybe_raises
  397.         {
  398.           tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($1), empty_parms (), $3);
  399.           $$ = start_method (TREE_CHAIN ($1), decl, $4);
  400.           if (! $$)
  401.             YYERROR;
  402.           if (yychar == YYEMPTY)
  403.             yychar = YYLEX;
  404.           reinit_parse_for_method (yychar, $$); }
  405.     | typed_declspecs declarator maybe_raises
  406.         { $$ = start_method ($1, $2, $3);
  407.           if (! $$)
  408.             YYERROR;
  409.           if (yychar == YYEMPTY)
  410.             yychar = YYLEX;
  411.           reinit_parse_for_method (yychar, $$); }
  412.     | declmods '(' parmlist ')' type_quals maybe_raises
  413.         {
  414.           tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($1), $3, $5);
  415.           $$ = start_method (TREE_CHAIN ($1), decl, $6);
  416.           if (! $$)
  417.             YYERROR;
  418.           if (yychar == YYEMPTY)
  419.             yychar = YYLEX;
  420.           reinit_parse_for_method (yychar, $$); }
  421.     | declmods LEFT_RIGHT type_quals maybe_raises
  422.         {
  423.           tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($1), empty_parms (), $3);
  424.           $$ = start_method (TREE_CHAIN ($1), decl, $4);
  425.           if (! $$)
  426.             YYERROR;
  427.           if (yychar == YYEMPTY)
  428.             yychar = YYLEX;
  429.           reinit_parse_for_method (yychar, $$); }
  430.     | declmods declarator maybe_raises
  431.         { $$ = start_method ($1, $2, $3);
  432.           if (! $$)
  433.             YYERROR;
  434.           if (yychar == YYEMPTY)
  435.             yychar = YYLEX;
  436.           reinit_parse_for_method (yychar, $$); }
  437.     | dummy_decl notype_declarator maybe_raises
  438.         { $$ = start_method (NULL_TREE, $2, $3);
  439.           if (! $$)
  440.             YYERROR;
  441.           if (yychar == YYEMPTY)
  442.             yychar = YYLEX;
  443.           reinit_parse_for_method (yychar, $$); }
  444.     ;
  445.  
  446. return_id: RETURN IDENTIFIER
  447.         {
  448.           if (! current_function_parms_stored)
  449.             store_parm_decls ();
  450.           $$ = $2;
  451.         }
  452.     ;
  453.  
  454. return_init: return_id opt.init
  455.         {
  456.           extern tree value_identifier;
  457.           tree result;
  458.  
  459.           result = DECL_RESULT (current_function_decl);
  460.           if (DECL_NAME (result) == value_identifier)
  461.             DECL_NAME (result) = $1;
  462.           else
  463.             error ("return identifier `%s' already in place",
  464.                IDENTIFIER_POINTER (DECL_NAME (result)));
  465.           store_return_init ($2);
  466.         }
  467.     | return_id '(' nonnull_exprlist ')'
  468.         {
  469.           extern tree value_identifier;
  470.           tree result;
  471.  
  472.           result = DECL_RESULT (current_function_decl);
  473.           if (DECL_NAME (result) == value_identifier)
  474.             DECL_NAME (result) = $1;
  475.           else
  476.             error ("return identifier `%s' already in place",
  477.                IDENTIFIER_POINTER (DECL_NAME (result)));
  478.           store_return_init ($3);
  479.         }
  480.     | return_id LEFT_RIGHT
  481.         {
  482.           extern tree value_identifier;
  483.           tree result;
  484.  
  485.           result = DECL_RESULT (current_function_decl);
  486.           if (DECL_NAME (result) == value_identifier)
  487.             DECL_NAME (result) = $1;
  488.           else
  489.             error ("return identifier `%s' already in place",
  490.                IDENTIFIER_POINTER (DECL_NAME (result)));
  491.           store_return_init (NULL_TREE);
  492.         }
  493.     ;
  494.  
  495. base_init:
  496.       ':' .set_base_init member_init_list
  497.         {
  498.           if ($3 == 0)
  499.             error ("no base initializers given following ':'");
  500.           setup_vtbl_ptr ();
  501.         }
  502.     ;
  503.  
  504. .set_base_init:
  505.     /* empty */
  506.         {
  507.           int preserve = (current_class_type
  508.                   && TYPE_USES_VIRTUAL_BASECLASSES (current_class_type));
  509.           preserve = 0;    /* "in charge" arg means we no longer
  510.                    need this hack.  */
  511.           if (! current_function_parms_stored)
  512.             store_parm_decls ();
  513.           else if (preserve)
  514.             preserve_data ();
  515.  
  516.           /* Flag that we are processing base and member initializers.  */
  517.           current_vtable_decl = error_mark_node;
  518.  
  519.           if (DECL_CONSTRUCTOR_P (current_function_decl))
  520.             {
  521.               /* Make a contour for the initializer list.  */
  522.               pushlevel (0);
  523.               clear_last_expr ();
  524.               expand_start_bindings (0);
  525.             }
  526.           else if (current_class_type == NULL_TREE)
  527.             error ("base initializers not allowed for non-member functions");
  528.           else if (! DECL_CONSTRUCTOR_P (current_function_decl))
  529.             error ("only constructors take base initializers");
  530.         }
  531.     ;
  532.  
  533. member_init_list:
  534.       /* empty */
  535.         { $$ = 0; }
  536.     | member_init
  537.         { $$ = 1; }
  538.     | member_init_list ',' member_init
  539.     | member_init_list error
  540.     ;
  541.  
  542.  
  543.  
  544. member_init: '(' nonnull_exprlist ')'
  545.         {
  546.           if (current_class_name && pedantic)
  547.             warning ("old style base class initialization; use `%s (...)'",
  548.                  IDENTIFIER_POINTER (current_class_name));
  549.           expand_member_init (C_C_D, NULL_TREE, $2);
  550.         }
  551.     | LEFT_RIGHT
  552.         {
  553.           if (current_class_name && pedantic)
  554.             warning ("old style base class initialization; use `%s (...)'",
  555.                  IDENTIFIER_POINTER (current_class_name));
  556.           expand_member_init (C_C_D, NULL_TREE, void_type_node);
  557.         }
  558.     | identifier '(' nonnull_exprlist ')'
  559.         {
  560.           expand_member_init (C_C_D, $1, $3);
  561.         }
  562.     | identifier LEFT_RIGHT
  563.         { expand_member_init (C_C_D, $1, void_type_node); }
  564.     | scoped_identifier identifier '(' nonnull_exprlist ')'
  565.         {
  566.           tree base, basetype;
  567.           tree scopes = $1;
  568.  
  569.           if (TREE_CODE (scopes) == SCOPE_REF)
  570.             /* just a pain to do this right now.  */
  571.             abort ();
  572.  
  573.           if (current_class_type == NULL_TREE
  574.               || ! is_aggr_typedef (scopes, 1))
  575.             break;
  576.           basetype = get_base_type (TREE_TYPE (TREE_TYPE (scopes)),
  577.                         current_class_type, 1);
  578.           if (basetype == error_mark_node)
  579.             break;
  580.           if (basetype == 0)
  581.             {
  582.               error_not_base_type (TREE_TYPE (TREE_TYPE (scopes)), current_class_type);
  583.               break;
  584.             }
  585.  
  586.           base = convert_pointer_to (basetype, current_class_decl);
  587.           expand_member_init (build_indirect_ref (base), $2, $4);
  588.         }
  589.     | scoped_identifier identifier LEFT_RIGHT
  590.         {
  591.           tree basetype, base;
  592.           tree scopes = $1;
  593.           if (TREE_CODE (scopes) == SCOPE_REF)
  594.             /* just a pain to do this right now.  */
  595.             abort ();
  596.  
  597.           if (current_class_type == NULL_TREE
  598.               || ! is_aggr_typedef (scopes, 1))
  599.             break;
  600.           basetype = get_base_type (TREE_TYPE (TREE_TYPE (scopes)),
  601.                         current_class_type, 1);
  602.           if (basetype == error_mark_node)
  603.             break;
  604.           if (basetype == 0)
  605.             {
  606.               error_not_base_type (TREE_TYPE (TREE_TYPE (scopes)), current_class_type);
  607.               break;
  608.             }
  609.  
  610.           base = convert_pointer_to (basetype, current_class_decl);
  611.           expand_member_init (build_indirect_ref (base), $2, void_type_node);
  612.         }
  613.     ;
  614.  
  615. identifier:
  616.       IDENTIFIER
  617.     | TYPENAME
  618.     ;
  619.  
  620. identifier_or_opname:
  621.       IDENTIFIER
  622.     | TYPENAME
  623.     | '~' identifier
  624.         { $$ = build_parse_node (BIT_NOT_EXPR, $2); }
  625.     | operator_name
  626.         { $$ = hack_operator ($1);
  627.           if ($$ == error_mark_node)
  628.             $$ = get_identifier ("<missing operator>"); }
  629.     | wrapper IDENTIFIER
  630.         { $$ = hack_wrapper ($1, NULL_TREE, $2); }
  631.     | wrapper TYPENAME
  632.         { $$ = hack_wrapper ($1, NULL_TREE, $2); }
  633.     | wrapper operator_name
  634.         { $$ = hack_wrapper ($1, NULL_TREE, $2); }
  635.     | wrapper scoped_identifier IDENTIFIER
  636.         { $$ = hack_wrapper ($1, $2, $3); }
  637.     | wrapper scoped_identifier operator_name
  638.         { $$ = hack_wrapper ($1, $2, $3); }
  639.     ;
  640.  
  641. wrapper:  LEFT_RIGHT
  642.         { $$ = 0; }
  643.     | '~' LEFT_RIGHT
  644.         { $$ = 1; }
  645.     | LEFT_RIGHT '?'
  646.         { $$ = 2; }
  647.     ;
  648.  
  649. unop:     '-'
  650.         { $$ = NEGATE_EXPR; }
  651.     | '+'
  652.         { $$ = CONVERT_EXPR; }
  653.     | PLUSPLUS
  654.         { $$ = PREINCREMENT_EXPR; }
  655.     | MINUSMINUS
  656.         { $$ = PREDECREMENT_EXPR; }
  657.     | '!'
  658.         { $$ = TRUTH_NOT_EXPR; }
  659.     ;
  660.  
  661. expr:      nonnull_exprlist
  662.         { $$ = build_x_compound_expr ($1); }
  663.     /* Ugly, but faster.  */
  664.     | expr_no_commas
  665.         {
  666.           if (TREE_CODE ($1) == CALL_EXPR
  667.               && TYPE_NEEDS_DESTRUCTOR (TREE_TYPE ($1)))
  668.             $$ = cleanup_after_call ($1);
  669.         }
  670.     ;
  671.  
  672. /* Now obsolete.
  673. exprlist:
  674.       / * empty * /
  675.         { $$ = NULL_TREE; }
  676.     | nonnull_exprlist
  677.     ;
  678. */
  679.  
  680. nonnull_exprlist:
  681.       expr_no_commas
  682.         { $$ = build_tree_list (NULL_TREE, $1); }
  683.     | nonnull_exprlist ',' expr_no_commas
  684.         { chainon ($1, build_tree_list (NULL_TREE, $3)); }
  685.     | nonnull_exprlist ',' error
  686.         { chainon ($1, build_tree_list (NULL_TREE, error_mark_node)); }
  687.     ;
  688.  
  689. unary_expr:
  690.       primary %prec UNARY
  691.         {
  692.           if (TREE_CODE ($1) == TYPE_EXPR)
  693.             $$ = build_component_type_expr (C_C_D, $1, NULL_TREE, 1);
  694.           else
  695.             $$ = $1;
  696.         }
  697.     | '*' cast_expr   %prec UNARY
  698.         { $$ = build_x_indirect_ref ($2, "unary *"); }
  699.     | '&' cast_expr   %prec UNARY
  700.         { $$ = build_x_unary_op (ADDR_EXPR, $2); }
  701.     | '~' cast_expr   %prec UNARY
  702.         { $$ = build_x_unary_op (BIT_NOT_EXPR, $2); }
  703.     | unop cast_expr  %prec UNARY
  704.         { $$ = build_x_unary_op ($1, $2);
  705.           if ($1 == NEGATE_EXPR && TREE_CODE ($2) == INTEGER_CST)
  706.             TREE_NEGATED_INT ($$) = 1;
  707.         }
  708.     | SIZEOF unary_expr  %prec UNARY
  709.         { if (TREE_CODE ($2) == COMPONENT_REF
  710.               && TREE_PACKED (TREE_OPERAND ($2, 1)))
  711.             error ("sizeof applied to a bit-field");
  712.           /* ANSI says arrays and functions are converted inside comma.
  713.              But we can't really convert them in build_compound_expr
  714.              because that would break commas in lvalues.
  715.              So do the conversion here if operand was a comma.  */
  716.           if (TREE_CODE ($2) == COMPOUND_EXPR
  717.               && (TREE_CODE (TREE_TYPE ($2)) == ARRAY_TYPE
  718.               || TREE_CODE (TREE_TYPE ($2)) == FUNCTION_TYPE))
  719.             $2 = default_conversion ($2);
  720.           $$ = c_sizeof (TREE_TYPE ($2)); }
  721.     | SIZEOF '(' typename ')'  %prec HYPERUNARY
  722.         { $$ = c_sizeof (groktypename ($3)); }
  723.     | ALIGNOF unary_expr  %prec UNARY
  724.         { if (TREE_CODE ($2) == COMPONENT_REF
  725.               && TREE_PACKED (TREE_OPERAND ($2, 1)))
  726.             error ("`__alignof' applied to a bit-field");
  727.           if (TREE_CODE ($2) == INDIRECT_REF)
  728.             {
  729.               tree t = TREE_OPERAND ($2, 0);
  730.               tree best = t;
  731.               int bestalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));
  732.               while (TREE_CODE (t) == NOP_EXPR
  733.                  && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == POINTER_TYPE)
  734.             {
  735.               int thisalign;
  736.               t = TREE_OPERAND (t, 0);
  737.               thisalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));
  738.               if (thisalign > bestalign)
  739.                 best = t, bestalign = thisalign;
  740.             }
  741.               $$ = c_alignof (TREE_TYPE (TREE_TYPE (best)));
  742.             }
  743.           else
  744.             {
  745.               /* ANSI says arrays and fns are converted inside comma.
  746.              But we can't convert them in build_compound_expr
  747.              because that would break commas in lvalues.
  748.              So do the conversion here if operand was a comma.  */
  749.               if (TREE_CODE ($2) == COMPOUND_EXPR
  750.               && (TREE_CODE (TREE_TYPE ($2)) == ARRAY_TYPE
  751.                   || TREE_CODE (TREE_TYPE ($2)) == FUNCTION_TYPE))
  752.             $2 = default_conversion ($2);
  753.               $$ = c_alignof (TREE_TYPE ($2));
  754.             }
  755.         }
  756.     | ALIGNOF '(' typename ')'  %prec HYPERUNARY
  757.         { $$ = c_alignof (groktypename ($3)); }
  758.  
  759.     | .scope new typename %prec '='
  760.         { $$ = build_new ($2, $3, NULL_TREE, $1); }
  761.     | .scope new x_typespec '(' nonnull_exprlist ')'
  762.         { $$ = build_new ($2, $3, $5, $1); }
  763.     | .scope new x_typespec LEFT_RIGHT
  764.         { $$ = build_new ($2, $3, NULL_TREE, $1); }
  765.     | .scope new typename '=' init %prec '='
  766.         { $$ = build_new ($2, $3, $5, $1); }
  767.     | .scope new '(' typename ')'
  768.         { $$ = build_new ($2, $4, NULL_TREE, $1); }
  769.     /* Unswallow a ':' which is probably meant for ?: expression.  */
  770.     | .scope new TYPENAME_COLON
  771.         { yyungetc (':', 1);
  772.           $$ = build_new ($2, $3, NULL_TREE, $1); }
  773.  
  774.     | delete cast_expr  %prec UNARY
  775.         { tree expr = stabilize_reference (convert_from_reference ($2));
  776.           tree type = TREE_TYPE (expr);
  777.  
  778.           if (integer_zerop (expr))
  779.             $$ = build1 (NOP_EXPR, void_type_node, expr);
  780.           else if (TREE_CODE (type) != POINTER_TYPE)
  781.             {
  782.               error ("non-pointer type to `delete'");
  783.               $$ = error_mark_node;
  784.               break;
  785.             }
  786.           if (TYPE_HAS_DESTRUCTOR (TREE_TYPE (type)))
  787.             $$ = build_delete (type, expr, integer_three_node,
  788.                        LOOKUP_NORMAL|LOOKUP_HAS_IN_CHARGE, $1);
  789.           else if (! TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (type)))
  790.             $$ = build_x_delete (type, expr, $1);
  791.           else
  792.             $$ = build_delete (type, expr, integer_three_node,
  793.                        LOOKUP_NORMAL|LOOKUP_HAS_IN_CHARGE, 0);
  794.         }
  795.     | delete '[' expr ']' cast_expr  %prec UNARY
  796.         {
  797.           tree maxindex = build_binary_op (MINUS_EXPR, $3, integer_one_node);
  798.           tree exp = stabilize_reference (convert_from_reference ($5));
  799.           tree elt_size = c_sizeof (TREE_TYPE (exp));
  800.  
  801.           if (yychar == YYEMPTY)
  802.             yychar = YYLEX;
  803.  
  804.           $$ = build_vec_delete (exp, maxindex, elt_size, NULL_TREE,
  805.                      integer_one_node, integer_two_node);
  806.         }
  807.     ;
  808.  
  809. cast_expr:
  810.       unary_expr
  811.     | '(' typename ')' expr_no_commas  %prec UNARY
  812.         { tree type = groktypename ($2);
  813.           $$ = build_c_cast (type, $4); }
  814.     | '(' typename ')' '{' initlist maybecomma '}'  %prec UNARY
  815.         { tree type = groktypename ($2);
  816.           tree init = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($5));
  817.           if (pedantic)
  818.             warning ("ANSI C forbids constructor-expressions");
  819.           /* Indicate that this was a GNU C constructor expression.  */
  820.           TREE_HAS_CONSTRUCTOR (init) = 1;
  821.           $$ = digest_init (type, init, 0);
  822.           if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0)
  823.             {
  824.               int failure = complete_array_type (type, $$, 1);
  825.               if (failure)
  826.             abort ();
  827.             }
  828.         }
  829.     ;
  830.  
  831. expr_no_commas:
  832.       cast_expr
  833.     | expr_no_commas '+' expr_no_commas
  834.         { $$ = build_x_binary_op ($2, $1, $3); }
  835.     | expr_no_commas '-' expr_no_commas
  836.         { $$ = build_x_binary_op ($2, $1, $3); }
  837.     | expr_no_commas '*' expr_no_commas
  838.         { $$ = build_x_binary_op ($2, $1, $3); }
  839.     | expr_no_commas '/' expr_no_commas
  840.         { $$ = build_x_binary_op ($2, $1, $3); }
  841.     | expr_no_commas '%' expr_no_commas
  842.         { $$ = build_x_binary_op ($2, $1, $3); }
  843.     | expr_no_commas LSHIFT expr_no_commas
  844.         { $$ = build_x_binary_op ($2, $1, $3); }
  845.     | expr_no_commas RSHIFT expr_no_commas
  846.         { $$ = build_x_binary_op ($2, $1, $3); }
  847.     | expr_no_commas ARITHCOMPARE expr_no_commas
  848.         { $$ = build_x_binary_op ($2, $1, $3); }
  849.     | expr_no_commas EQCOMPARE expr_no_commas
  850.         { $$ = build_x_binary_op ($2, $1, $3); }
  851.     | expr_no_commas MIN_MAX expr_no_commas
  852.         { $$ = build_x_binary_op ($2, $1, $3); }
  853.     | expr_no_commas '&' expr_no_commas
  854.         { $$ = build_x_binary_op ($2, $1, $3); }
  855.     | expr_no_commas '|' expr_no_commas
  856.         { $$ = build_x_binary_op ($2, $1, $3); }
  857.     | expr_no_commas '^' expr_no_commas
  858.         { $$ = build_x_binary_op ($2, $1, $3); }
  859.     | expr_no_commas ANDAND expr_no_commas
  860.         { $$ = build_x_binary_op (TRUTH_ANDIF_EXPR, $1, $3); }
  861.     | expr_no_commas OROR expr_no_commas
  862.         { $$ = build_x_binary_op (TRUTH_ORIF_EXPR, $1, $3); }
  863.     | expr_no_commas '?' xexpr ':' expr_no_commas
  864.         { $$ = build_x_conditional_expr ($1, $3, $5); }
  865.     | expr_no_commas '=' expr_no_commas
  866.         { $$ = build_modify_expr ($1, NOP_EXPR, $3); }
  867.     | expr_no_commas ASSIGN expr_no_commas
  868.         { register tree rval;
  869.           if (rval = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL, $1, $3, $2))
  870.             $$ = rval;
  871.           else
  872.             $$ = build_modify_expr ($1, $2, $3); }
  873.  
  874.     /* Handle general members.  */
  875.     | object '*' expr_no_commas   %prec UNARY
  876.         { $$ = build_m_component_ref ($1, build_x_indirect_ref ($3, "unary *")); }
  877.     | object '&' expr_no_commas   %prec UNARY
  878.         { $$ = build_m_component_ref ($1, build_x_unary_op (ADDR_EXPR, $3)); }
  879.     | object unop expr_no_commas  %prec UNARY
  880.         { $$ = build_m_component_ref ($1, build_x_unary_op ($2, $3)); }
  881.     | object '(' typename ')' expr_no_commas  %prec UNARY
  882.         { tree type = groktypename ($3);
  883.           $$ = build_m_component_ref ($1, build_c_cast (type, $5)); }
  884.     | object primary_no_id  %prec UNARY
  885.         { $$ = build_m_component_ref ($1, $2); }
  886.     ;
  887.  
  888. primary:
  889.     IDENTIFIER
  890.         { $$ = do_identifier ($1); }
  891.     | operator_name
  892.         {
  893.           tree op = hack_operator ($1);
  894.           if (TREE_CODE (op) != IDENTIFIER_NODE)
  895.             $$ = op;
  896.           else
  897.             {
  898.               $$ = lookup_name (op);
  899.               if ($$ == NULL_TREE)
  900.             {
  901.               error ("operator %s not defined", operator_name_string (op));
  902.               $$ = error_mark_node;
  903.             }
  904.             }
  905.         }
  906.     | CONSTANT
  907.     | string
  908.         { $$ = combine_strings ($1); }
  909.     | '(' expr ')'
  910.         { $$ = $2; }
  911.     | '(' error ')'
  912.         { $$ = error_mark_node; }
  913.     | '('
  914.         { if (current_function_decl == 0)
  915.             {
  916.               error ("braced-group within expression allowed only inside a function");
  917.               YYERROR;
  918.             }
  919.           keep_next_level ();
  920.           $<ttype>$ = expand_start_stmt_expr (); }
  921.       compstmt ')'
  922.         { tree rtl_exp;
  923.           if (pedantic)
  924.             warning ("ANSI C forbids braced-groups within expressions");
  925.           rtl_exp = expand_end_stmt_expr ($<ttype>2);
  926.           $$ = $3;
  927.           TREE_USED ($$) = 0;
  928.           /* Since the statements have side effects,
  929.              consider this volatile.  */
  930.           TREE_VOLATILE ($$) = 1;
  931.           TREE_TYPE ($$) = TREE_TYPE (rtl_exp);
  932.           STMT_BODY ($$) = rtl_exp; }
  933.     | primary '(' nonnull_exprlist ')'
  934.         { $$ = build_x_function_call ($1, $3, current_class_decl); }
  935.     | primary LEFT_RIGHT
  936.         { $$ = build_x_function_call ($1, NULL_TREE, current_class_decl); }
  937.     | primary '[' expr ']'
  938.         {
  939.         do_array:
  940.           {
  941.             tree type = TREE_TYPE ($1);
  942.             if (type == error_mark_node || $3 == error_mark_node)
  943.               $$ = error_mark_node;
  944.             else if (type == NULL_TREE)
  945.               {
  946.             /* Something has gone very wrong.  Assume we
  947.                are mistakenly reducing an expression
  948.                instead of a declaration.  */
  949.             error ("parser may be lost: is there a '{' missing somewhere?");
  950.             $$ = NULL_TREE;
  951.               }
  952.             else
  953.               {
  954.             if (TREE_CODE (type) == OFFSET_TYPE)
  955.               type = TREE_TYPE (type);
  956.             if (TREE_CODE (type) == REFERENCE_TYPE)
  957.               type = TREE_TYPE (type);
  958.  
  959.             if (TYPE_LANG_SPECIFIC (type) &&
  960.                 TYPE_OVERLOADS_ARRAY_REF (type))
  961.               $$ = build_opfncall (ARRAY_REF, LOOKUP_NORMAL, $1, $3);
  962.             else if (TREE_CODE (type) == POINTER_TYPE
  963.                  || TREE_CODE (type) == ARRAY_TYPE)
  964.               $$ = build_array_ref ($1, $3);
  965.             else
  966.               error("[] applied to non-pointer type");
  967.               }
  968.           }
  969.         }
  970.     | object identifier_or_opname  %prec UNARY
  971.         { $$ = build_component_ref ($1, $2, NULL_TREE, 1); }
  972.     | object scoped_identifier identifier_or_opname %prec UNARY
  973.         {
  974.           tree basetype = (TREE_CODE ($2) == SCOPE_REF) ? TREE_OPERAND ($2, 1) : $2;
  975.           if (is_aggr_typedef (basetype, 1))
  976.             {
  977.               basetype = TREE_TYPE (TREE_TYPE (basetype));
  978.  
  979.               if ($1 == error_mark_node)
  980.             $$ = error_mark_node;
  981.               else if (basetype_or_else (basetype, TREE_TYPE ($1)))
  982.             $$ = build_component_ref (build_scoped_ref ($1, $2), $3, NULL_TREE, 1);
  983.               else
  984.             $$ = error_mark_node;
  985.             }
  986.           else $$ = error_mark_node;
  987.         }
  988.     | primary PLUSPLUS
  989.         { $$ = build_x_unary_op (POSTINCREMENT_EXPR, $1); }
  990.     | primary MINUSMINUS
  991.         { $$ = build_x_unary_op (POSTDECREMENT_EXPR, $1); }
  992.  
  993.     /* C++ extensions */
  994.     | THIS
  995.         { if (current_class_decl)
  996.             {
  997. #ifdef WARNING_ABOUT_CCD
  998.               TREE_USED (current_class_decl) = 1;
  999. #endif
  1000.               $$ = current_class_decl;
  1001.             }
  1002.           else if (current_function_decl
  1003.                && DECL_STATIC_FUNCTION_P (current_function_decl))
  1004.             {
  1005.               error ("`this' is unavailable for static member functions");
  1006.               $$ = error_mark_node;
  1007.             }
  1008.           else
  1009.             {
  1010.               if (current_function_decl)
  1011.             error ("invalid use of `this' in non-member function");
  1012.               else
  1013.             error ("invalid use of `this' at top level");
  1014.               $$ = error_mark_node;
  1015.             }
  1016.         }
  1017.     | dummy_decl TYPE_QUAL '(' nonnull_exprlist ')'
  1018.         {
  1019.           tree type;
  1020.           tree id = $2;
  1021.  
  1022.           /* This is a C cast in C++'s `functional' notation.  */
  1023.           if ($4 == error_mark_node)
  1024.             {
  1025.               $$ = error_mark_node;
  1026.               break;
  1027.             }
  1028. #if 0
  1029.           if ($4 == NULL_TREE)
  1030.             {
  1031.               error ("cannot cast null list to type `%s'",
  1032.                      IDENTIFIER_POINTER (TYPE_NAME ($2)));
  1033.               $$ = error_mark_node;
  1034.               break;
  1035.             }
  1036. #endif
  1037.           if (type == error_mark_node)
  1038.             $$ = error_mark_node;
  1039.           else
  1040.             {
  1041.               if (id == ridpointers[(int) RID_CONST])
  1042.                 type = build_type_variant (integer_type_node, 1, 0);
  1043.               else if (id == ridpointers[(int) RID_VOLATILE])
  1044.                 type = build_type_variant (integer_type_node, 0, 1);
  1045.               else if (id == ridpointers[(int) RID_FRIEND])
  1046.                 {
  1047.                   error ("cannot cast expression to `friend' type");
  1048.                   $$ = error_mark_node;
  1049.                   break;
  1050.                 }
  1051.               else abort ();
  1052.               $$ = build_c_cast (type, build_compound_expr ($4));
  1053.             }
  1054.         }
  1055.     | x_typespec '(' nonnull_exprlist ')'
  1056.         { $$ = build_functional_cast ($1, $3); }
  1057.     | x_typespec LEFT_RIGHT
  1058.         { $$ = build_functional_cast ($1, NULL_TREE); }
  1059.     | SCOPE IDENTIFIER
  1060.         {
  1061.         do_scoped_identifier:
  1062.           $$ = IDENTIFIER_GLOBAL_VALUE ($2);
  1063.           if (yychar == YYEMPTY)
  1064.             yychar = YYLEX;
  1065.           if (! $$)
  1066.             {
  1067.               if (yychar == '(' || yychar == LEFT_RIGHT)
  1068.             {
  1069.               $$ = implicitly_declare ($2);
  1070.             }
  1071.               else
  1072.             {
  1073.               if (IDENTIFIER_GLOBAL_VALUE ($2) != error_mark_node)
  1074.                 error ("undeclared variable `%s' (first use here)",
  1075.                    IDENTIFIER_POINTER ($2));
  1076.               $$ = error_mark_node;
  1077.               /* Prevent repeated error messages.  */
  1078.               IDENTIFIER_GLOBAL_VALUE ($2) = error_mark_node;
  1079.             }
  1080.             }
  1081.           else if (TREE_CODE ($$) == CONST_DECL)
  1082.             $$ = DECL_INITIAL ($$);
  1083.           if (! TREE_USED ($$))
  1084.             {
  1085.               if (TREE_EXTERNAL ($$))
  1086.             assemble_external ($$);
  1087.               TREE_USED ($$) = 1;
  1088.             }
  1089.         }
  1090.     | SCOPE operator_name
  1091.         {
  1092.           $2 = hack_operator ($2);
  1093.           if (TREE_CODE ($2) == IDENTIFIER_NODE)
  1094.             goto do_scoped_identifier;
  1095.         do_scoped_operator:
  1096.           $$ = $2;
  1097.         }
  1098.     | scoped_identifier identifier_or_opname  %prec HYPERUNARY
  1099.         { $$ = build_offset_ref ($1, $2); }
  1100.     | scoped_identifier identifier_or_opname '(' nonnull_exprlist ')'
  1101.         { $$ = build_member_call ($1, $2, $4); }
  1102.     | scoped_identifier identifier_or_opname LEFT_RIGHT
  1103.         { $$ = build_member_call ($1, $2, NULL_TREE); }
  1104.  
  1105.     | object identifier_or_opname '(' nonnull_exprlist ')'
  1106.         { $$ = build_method_call ($1, $2, $4, NULL_TREE,
  1107.                       (LOOKUP_NORMAL|LOOKUP_AGGR)); }
  1108.     | object identifier_or_opname LEFT_RIGHT
  1109.         { $$ = build_method_call ($1, $2, NULL_TREE, NULL_TREE,
  1110.                       (LOOKUP_NORMAL|LOOKUP_AGGR)); }
  1111.     | object scoped_identifier identifier_or_opname '(' nonnull_exprlist ')'
  1112.         { $$ = build_scoped_method_call ($1, $2, $3, $5); }
  1113.     | object scoped_identifier identifier_or_opname LEFT_RIGHT
  1114.         { $$ = build_scoped_method_call ($1, $2, $3, NULL_TREE); }
  1115.     ;
  1116.  
  1117. primary_no_id:
  1118.       '(' expr ')'
  1119.         { $$ = $2; }
  1120.     | '(' error ')'
  1121.         { $$ = error_mark_node; }
  1122.     | '('
  1123.         { if (current_function_decl == 0)
  1124.             {
  1125.               error ("braced-group within expression allowed only inside a function");
  1126.               YYERROR;
  1127.             }
  1128.           $<ttype>$ = expand_start_stmt_expr (); }
  1129.       compstmt ')'
  1130.         { if (pedantic)
  1131.             warning ("ANSI C forbids braced-groups within expressions");
  1132.           $$ = expand_end_stmt_expr ($<ttype>2); }
  1133.     | primary_no_id '(' nonnull_exprlist ')'
  1134.         { $$ = build_x_function_call ($1, $3, current_class_decl); }
  1135.     | primary_no_id LEFT_RIGHT
  1136.         { $$ = build_x_function_call ($1, NULL_TREE, current_class_decl); }
  1137.     | primary_no_id '[' expr ']'
  1138.         { goto do_array; }
  1139.     | primary_no_id PLUSPLUS
  1140.         { $$ = build_x_unary_op (POSTINCREMENT_EXPR, $1); }
  1141.     | primary_no_id MINUSMINUS
  1142.         { $$ = build_x_unary_op (POSTDECREMENT_EXPR, $1); }
  1143.     | SCOPE IDENTIFIER
  1144.         { goto do_scoped_identifier; }
  1145.     | SCOPE operator_name
  1146.         { $2 = hack_operator ($2);
  1147.           if (TREE_CODE ($2) == IDENTIFIER_NODE)
  1148.             goto do_scoped_identifier;
  1149.           goto do_scoped_operator;
  1150.         }
  1151.     ;
  1152.  
  1153. new:      NEW
  1154.         { $$ = NULL_TREE; }
  1155.     | NEW '{' nonnull_exprlist '}'
  1156.         { $$ = $3; }
  1157.     | NEW DYNAMIC  %prec EMPTY
  1158.         { $$ = void_type_node; }
  1159.     | NEW DYNAMIC '(' string ')'
  1160.         { $$ = combine_strings ($4); }
  1161.     ;
  1162.  
  1163. .scope:
  1164.     /* empty  */
  1165.         { $$ = 0; }
  1166.     | SCOPE
  1167.         { $$ = 1; }
  1168.     ;
  1169.  
  1170. delete:      DELETE
  1171.         { $$ = NULL_TREE; }
  1172.     | SCOPE delete
  1173.         { if ($2)
  1174.             error ("extra `::' before `delete' ignored");
  1175.           $$ = error_mark_node;
  1176.         }
  1177.     ;
  1178.  
  1179. /* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it.  */
  1180. string:
  1181.       STRING
  1182.     | string STRING
  1183.         { $$ = chainon ($1, $2); }
  1184.     ;
  1185.  
  1186. nodecls:
  1187.       /* empty */
  1188.         {
  1189.           if (! current_function_parms_stored)
  1190.             store_parm_decls ();
  1191.           setup_vtbl_ptr ();
  1192.         }
  1193.     ;
  1194.  
  1195. object:      primary '.'
  1196.         {
  1197.           if ($1 == error_mark_node)
  1198.             $$ = error_mark_node;
  1199.           else
  1200.             {
  1201.               tree type = TREE_TYPE ($1);
  1202.  
  1203.               if (IS_AGGR_TYPE (type)
  1204.               || (TREE_CODE (type) == REFERENCE_TYPE
  1205.                   && IS_AGGR_TYPE (TREE_TYPE (type))))
  1206.             $$ = $1;
  1207.               else
  1208.             {
  1209.               error ("object in '.' expression is not of aggregate type");
  1210.               $$ = error_mark_node;
  1211.             }
  1212.             }
  1213.         }
  1214.     | primary POINTSAT
  1215.         {
  1216.           $$ = build_x_arrow ($1);
  1217.         }
  1218.     ;
  1219.  
  1220. decl:
  1221.       typed_declspecs initdecls ';'
  1222.         {
  1223.           resume_momentary ($2);
  1224.           note_got_semicolon ($1);
  1225.         }
  1226.     /* Normal case: make this fast.  */
  1227.     | typed_declspecs declarator ';'
  1228.         { tree d;
  1229.           int yes = suspend_momentary ();
  1230.           d = start_decl ($2, $1, 0, NULL_TREE);
  1231.           finish_decl (d, NULL_TREE, NULL_TREE);
  1232.           resume_momentary (yes);
  1233.           note_got_semicolon ($1);
  1234.         }
  1235.     | declmods notype_initdecls ';'
  1236.         { resume_momentary ($2); }
  1237.     /* Normal case: make this fast.  */
  1238.     | declmods declarator ';'
  1239.         { tree d;
  1240.           int yes = suspend_momentary ();
  1241.           d = start_decl ($2, $1, 0, NULL_TREE);
  1242.           finish_decl (d, NULL_TREE, NULL_TREE);
  1243.           resume_momentary (yes);
  1244.         }
  1245.     | typed_declspecs ';'
  1246.         {
  1247.           shadow_tag ($1);
  1248.           note_got_semicolon ($1);
  1249.         }
  1250.     | declmods ';'
  1251.         { warning ("empty declaration"); }
  1252.     ;
  1253.  
  1254. /* Any kind of declarator (thus, all declarators allowed
  1255.    after an explicit typespec).  */
  1256.  
  1257. declarator:
  1258.       after_type_declarator
  1259.     | notype_declarator
  1260.     ;
  1261.  
  1262. /* Declspecs which contain at least one type specifier or typedef name.
  1263.    (Just `const' or `volatile' is not enough.)
  1264.    A typedef'd name following these is taken as a name to be declared.  */
  1265.  
  1266. typed_declspecs:
  1267.       x_typespec
  1268.         { $$ = list_hash_lookup_or_cons ($1); }
  1269.     | declmods typespec
  1270.         { $$ = hash_tree_chain ($2, $1); }
  1271.     | x_typespec reserved_declspecs
  1272.         { $$ = hash_tree_chain ($1, $2); }
  1273.     | declmods typespec reserved_declspecs
  1274.         { $$ = hash_tree_chain ($2, hash_chainon ($3, $1)); }
  1275.     ;
  1276.  
  1277. reserved_declspecs:  /* empty
  1278.         { $$ = NULL_TREE; } */
  1279.       typespecqual_reserved
  1280.         { $$ = build_decl_list (NULL_TREE, $1); }
  1281.     | SCSPEC
  1282.         { $$ = build_decl_list (NULL_TREE, $1); }
  1283.     | reserved_declspecs typespecqual_reserved
  1284.         { $$ = decl_tree_cons (NULL_TREE, $2, $1); }
  1285.     | reserved_declspecs SCSPEC
  1286.         { $$ = decl_tree_cons (NULL_TREE, $2, $1); }
  1287.     ;
  1288.  
  1289. /* List of just storage classes and type modifiers.
  1290.    A declaration can start with just this, but then it cannot be used
  1291.    to redeclare a typedef-name.  */
  1292.  
  1293. declmods:
  1294.       dummy_decl TYPE_QUAL
  1295.         { $$ = IDENTIFIER_AS_LIST ($2); }
  1296.     | dummy_decl SCSPEC
  1297.         { $$ = IDENTIFIER_AS_LIST ($2); }
  1298.     | declmods TYPE_QUAL
  1299.         { $$ = hash_tree_chain ($2, $1); }
  1300.     | declmods SCSPEC
  1301.         { $$ = hash_tree_chain ($2, $1); }
  1302.     ;
  1303.  
  1304.  
  1305. /* Used instead of declspecs where storage classes are not allowed
  1306.    (that is, for typenames and structure components).
  1307.  
  1308.    C++ can takes storage classes for structure components.
  1309.    Don't accept a typedef-name if anything but a modifier precedes it.  */
  1310.  
  1311. typed_typespecs:
  1312.       x_typespec  %prec EMPTY
  1313.         { $$ = build_decl_list_1 ($1); }
  1314.     | nonempty_type_quals typespec
  1315.         { $$ = decl_tree_cons (NULL_TREE, $2, $1); }
  1316.     | x_typespec reserved_typespecquals
  1317.         { $$ = decl_tree_cons (NULL_TREE, $1, $2); }
  1318.     | nonempty_type_quals typespec reserved_typespecquals
  1319.         { $$ = decl_tree_cons (NULL_TREE, $2, hash_chainon ($3, $1)); }
  1320.     ;
  1321.  
  1322. reserved_typespecquals:
  1323.       typespecqual_reserved
  1324.         { $$ = build_decl_list_1 ($1); }
  1325.     | reserved_typespecquals typespecqual_reserved
  1326.         { $$ = decl_tree_cons (NULL_TREE, $2, $1); }
  1327.     ;
  1328.  
  1329. /* A typespec (but not a type qualifier).
  1330.    Once we have seen one of these in a declaration,
  1331.    if a typedef name appears then it is being redeclared.  */
  1332.  
  1333. typespec: TYPESPEC
  1334.     | structsp
  1335.     | TYPENAME
  1336.     | TYPEOF '(' expr ')'
  1337.         { $$ = TREE_TYPE ($3);
  1338.           if (pedantic)
  1339.             warning ("ANSI C forbids `typeof'"); }
  1340.     | TYPEOF '(' typename ')'
  1341.         { $$ = groktypename ($3);
  1342.           if (pedantic)
  1343.             warning ("ANSI C forbids `typeof'"); }
  1344.     ;
  1345.  
  1346. /* A typespec that is a reserved word, or a type qualifier.  */
  1347.  
  1348. typespecqual_reserved: TYPESPEC
  1349.     | TYPE_QUAL
  1350.     | structsp
  1351.     ;
  1352.  
  1353. x_typespec:
  1354.       dummy_decl TYPESPEC
  1355.         { $$ = $2; }
  1356.     | dummy_decl structsp
  1357.         { $$ = $2; }
  1358.     | dummy_decl TYPENAME
  1359.         { $$ = $2; }
  1360.     | dummy_decl TYPEOF '(' expr ')'
  1361.         { $$ = TREE_TYPE ($4);
  1362.           if (pedantic)
  1363.             warning ("ANSI C forbids `typeof'") }
  1364.     | dummy_decl TYPEOF '(' typename ')'
  1365.         { $$ = groktypename ($4);
  1366.           if (pedantic)
  1367.             warning ("ANSI C forbids `typeof'") }
  1368.     ;
  1369.  
  1370. initdecls:
  1371.       initdcl0
  1372.     | initdecls ',' initdcl
  1373.     ;
  1374.  
  1375. notype_initdecls:
  1376.       notype_initdcl0
  1377.     | notype_initdecls ',' initdcl
  1378.     ;
  1379.  
  1380. maybeasm:
  1381.       /* empty */
  1382.         { $$ = NULL_TREE; }
  1383.     | ASM '(' string ')'
  1384.         { if (TREE_CHAIN ($3)) $3 = combine_strings ($3);
  1385.           $$ = $3;
  1386.           if (pedantic)
  1387.             warning ("ANSI C forbids use of `asm' keyword");
  1388.         }
  1389.     ;
  1390.  
  1391. initdcl0:
  1392.       declarator maybe_raises maybeasm maybe_attribute '='
  1393.         { current_declspecs = $<ttype>0;
  1394.           $<itype>5 = suspend_momentary ();
  1395.           $<ttype>$ = start_decl ($1, current_declspecs, 1, $2); }
  1396.       init
  1397. /* Note how the declaration of the variable is in effect while its init is parsed! */
  1398.         { finish_decl ($<ttype>6, $7, $3);
  1399.           $$ = $<itype>5; }
  1400.     | declarator maybe_raises maybeasm maybe_attribute
  1401.         { tree d;
  1402.           current_declspecs = $<ttype>0;
  1403.           $$ = suspend_momentary ();
  1404.           d = start_decl ($1, current_declspecs, 0, $2);
  1405.           finish_decl (d, NULL_TREE, $3); }
  1406.     ;
  1407.  
  1408. initdcl:
  1409.       declarator maybe_raises maybeasm maybe_attribute '='
  1410.         { $<ttype>$ = start_decl ($1, current_declspecs, 1, $2); }
  1411.       init
  1412. /* Note how the declaration of the variable is in effect while its init is parsed! */
  1413.         { finish_decl ($<ttype>6, $7, $3); }
  1414.     | declarator maybe_raises maybeasm maybe_attribute
  1415.         { tree d = start_decl ($1, current_declspecs, 0, $2);
  1416.           finish_decl (d, NULL_TREE, $3); }
  1417.     ;
  1418.  
  1419. notype_initdcl0:
  1420.       notype_declarator maybe_raises maybeasm maybe_attribute '='
  1421.         { current_declspecs = $<ttype>0;
  1422.           $<itype>5 = suspend_momentary ();
  1423.           $<ttype>$ = start_decl ($1, current_declspecs, 1, $2); }
  1424.       init
  1425. /* Note how the declaration of the variable is in effect while its init is parsed! */
  1426.         { finish_decl ($<ttype>6, $7, $3);
  1427.           $$ = $<itype>5; }
  1428.     | notype_declarator maybe_raises maybeasm maybe_attribute
  1429.         { tree d;
  1430.           current_declspecs = $<ttype>0;
  1431.           $$ = suspend_momentary ();
  1432.           d = start_decl ($1, current_declspecs, 0, $2);
  1433.           finish_decl (d, NULL_TREE, $3); }
  1434.     ;
  1435.  
  1436. /* the * rules are dummies to accept the Apollo extended syntax
  1437.    so that the header files compile. */
  1438. maybe_attribute:
  1439.     /* empty */
  1440.     { $$ = NULL_TREE; }
  1441.     | ATTRIBUTE '(' '(' attribute_list ')' ')'
  1442.         { $$ = $4; }
  1443.     ;
  1444.  
  1445. attribute_list
  1446.     : attrib
  1447.     | attribute_list ',' attrib
  1448.     ;
  1449.  
  1450. attrib
  1451.     : IDENTIFIER
  1452.     { warning ("`%s' attribute directive ignored",
  1453.            IDENTIFIER_POINTER ($1));
  1454.       $$ = $1; }
  1455.     | IDENTIFIER '(' CONSTANT ')'
  1456.     { /* if not "aligned(1)", then issue warning */
  1457.       if (strcmp (IDENTIFIER_POINTER ($1), "aligned") != 0
  1458.           || TREE_CODE ($3) != INTEGER_CST
  1459.           || TREE_INT_CST_LOW ($3) != 1)
  1460.         warning ("`%s' attribute directive ignored",
  1461.              IDENTIFIER_POINTER ($1));
  1462.       $$ = $1; }
  1463.     | IDENTIFIER '(' identifiers ')'
  1464.     { warning ("`%s' attribute directive ignored",
  1465.            IDENTIFIER_POINTER ($1));
  1466.       $$ = $1; }
  1467.     ;
  1468.  
  1469. identifiers:
  1470.       IDENTIFIER
  1471.         { }
  1472.     | identifiers ',' IDENTIFIER
  1473.         { }
  1474.     ;
  1475.  
  1476. init:
  1477.       expr_no_commas %prec '='
  1478.     | '{' '}'
  1479.         { $$ = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE);
  1480.           TREE_HAS_CONSTRUCTOR ($$) = 1;
  1481.           if (pedantic)
  1482.             warning ("ANSI C forbids empty initializer braces"); }
  1483.     | '{' initlist '}'
  1484.         { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2));
  1485.           TREE_HAS_CONSTRUCTOR ($$) = 1; }
  1486.     | '{' initlist ',' '}'
  1487.         { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2));
  1488.           TREE_HAS_CONSTRUCTOR ($$) = 1; }
  1489.     | error
  1490.         { $$ = NULL_TREE; }
  1491.     ;
  1492.  
  1493. /* This chain is built in reverse order,
  1494.    and put in forward order where initlist is used.  */
  1495. initlist:
  1496.       init
  1497.         { $$ = build_tree_list (NULL_TREE, $1); }
  1498.     | initlist ',' init
  1499.         { $$ = tree_cons (NULL_TREE, $3, $1); }
  1500.     ;
  1501.  
  1502. structsp:
  1503.       ENUM identifier '{'
  1504.         { $<itype>3 = suspend_momentary ();
  1505.           $$ = start_enum ($2); }
  1506.       enumlist maybecomma_warn '}'
  1507.         { $$ = finish_enum ($<ttype>4, $5);
  1508.           resume_momentary ($<itype>3);
  1509.           check_for_missing_semicolon ($<ttype>4); }
  1510.     | ENUM identifier '{' '}'
  1511.         { $$ = finish_enum (start_enum ($2), NULL_TREE);
  1512.           check_for_missing_semicolon ($$); }
  1513.     | ENUM '{'
  1514.         { $<itype>2 = suspend_momentary ();
  1515.           $$ = start_enum (make_anon_name ()); }
  1516.       enumlist maybecomma_warn '}'
  1517.         { $$ = finish_enum ($<ttype>3, $4);
  1518.           resume_momentary ($<itype>1);
  1519.           check_for_missing_semicolon ($<ttype>3); }
  1520.     | ENUM '{' '}'
  1521.         { $$ = finish_enum (start_enum (make_anon_name()), NULL_TREE);
  1522.           check_for_missing_semicolon ($$); }
  1523.     | ENUM identifier
  1524.         { $$ = xref_tag (enum_type_node, $2, NULL_TREE); }
  1525.  
  1526.     /* C++ extensions, merged with C to avoid shift/reduce conflicts */
  1527.     | class_head LC opt.component_decl_list '}'
  1528.         {
  1529.           if (TREE_CODE ($1) == ENUMERAL_TYPE)
  1530.             $$ = $1;
  1531.           else if (CLASSTYPE_DECLARED_EXCEPTION ($1))
  1532.             $$ = finish_exception ($1, $3);
  1533.           else
  1534.             $$ = finish_struct ($1, $3, 0, 0);
  1535.             
  1536.           if ($2 & 1)
  1537.             resume_temporary_allocation ();
  1538.           if ($2 & 2)
  1539.             resume_momentary (1);
  1540.           check_for_missing_semicolon ($$);
  1541.         }
  1542.     | class_head LC opt.component_decl_list '}' ';'
  1543.         { if (TREE_CODE ($1) == ENUMERAL_TYPE)
  1544.             $$ = $1;
  1545.           else if (CLASSTYPE_DECLARED_EXCEPTION ($1))
  1546.             warning ("empty exception declaration\n");
  1547.           else
  1548.             $$ = finish_struct ($1, $3, 1, 1);
  1549.           if ($2 & 1)
  1550.             resume_temporary_allocation ();
  1551.           if ($2 & 2)
  1552.             resume_momentary (1);
  1553.           note_got_semicolon ($$);
  1554.           yyungetc (';', 0); }
  1555.     | class_head  %prec EMPTY
  1556.         { $$ = $1; }
  1557.     ;
  1558.  
  1559. maybecomma:
  1560.       /* empty */
  1561.     | ','
  1562.     ;
  1563.  
  1564. maybecomma_warn:
  1565.       /* empty */
  1566.     | ','
  1567.         { if (pedantic) warning ("comma at end of enumerator list"); }
  1568.     ;
  1569.  
  1570. aggr:      AGGR
  1571.         { $$ = $1; }
  1572.     | DYNAMIC AGGR
  1573.         { $$ = build_tree_list (NULL_TREE, $2); }
  1574.     | DYNAMIC '(' string ')' AGGR
  1575.         { $$ = build_tree_list ($3, $5); }
  1576.     | aggr SCSPEC
  1577.         { error ("storage class specifier `%s' not allow after struct or class", IDENTIFIER_POINTER ($2));
  1578.         }
  1579.     | aggr TYPESPEC
  1580.         { error ("type specifier `%s' not allow after struct or class", IDENTIFIER_POINTER ($2));
  1581.         }
  1582.     | aggr TYPE_QUAL
  1583.         { error ("type qualifier `%s' not allow after struct or class", IDENTIFIER_POINTER ($2));
  1584.         }
  1585.     | aggr AGGR
  1586.         { error ("no body nor ';' separates two class, struct or union declarations");
  1587.         }
  1588.  
  1589. class_head:
  1590.       aggr  %prec EMPTY
  1591.         { $$ = xref_tag ($1, make_anon_name (), NULL_TREE); }
  1592.     | aggr identifier  %prec EMPTY
  1593.         { $$ = xref_tag ($1, $2, NULL_TREE); }
  1594.     | aggr IDENTIFIER ':' base_class_list  %prec EMPTY
  1595.         { $$ = xref_tag ($1, $2, $4); }
  1596.     | aggr TYPENAME_COLON  %prec EMPTY
  1597.         { yyungetc (':', 1);
  1598.           $$ = xref_tag ($1, $2, NULL_TREE); }
  1599.     | aggr TYPENAME_COLON base_class_list  %prec EMPTY
  1600.         { $$ = xref_tag ($1, $2, $3); }
  1601.     ;
  1602.  
  1603. base_class_list:
  1604.       identifier
  1605.         { if (! is_aggr_typedef ($1, 1))
  1606.             $$ = NULL_TREE;
  1607.           else $$ = build_tree_list ((tree)visibility_default, $1); }
  1608.     | base_class_visibility_list identifier
  1609.         { if (! is_aggr_typedef ($2, 1))
  1610.             $$ = NULL_TREE;
  1611.           else $$ = build_tree_list ($1, $2); }
  1612.     | base_class_list ',' identifier
  1613.         { if (! is_aggr_typedef ($3, 1))
  1614.             $$ = NULL_TREE;
  1615.           else $$ = chainon ($1, build_tree_list ((tree)visibility_default, $3)); }
  1616.     | base_class_list ',' base_class_visibility_list identifier
  1617.         { if (! is_aggr_typedef ($4, 1))
  1618.             $$ = NULL_TREE;
  1619.           else $$ = chainon ($1, build_tree_list ($3, $4)); }
  1620.     ;
  1621.  
  1622. base_class_visibility_list:
  1623.       PUBLIC
  1624.         { $$ = (tree)visibility_public; }
  1625.     | PRIVATE
  1626.         { $$ = (tree)visibility_private; }
  1627.     | SCSPEC
  1628.         { if ($1 != ridpointers[(int)RID_VIRTUAL])
  1629.             sorry ("non-virtual visibility");
  1630.           $$ = (tree)visibility_default_virtual; }
  1631.     | base_class_visibility_list PUBLIC
  1632.         { if ($1 == (tree)visibility_private)
  1633.             error ("base class cannot be public and private");
  1634.           else if ($1 == (tree)visibility_default_virtual)
  1635.             $$ = (tree)visibility_public_virtual; }
  1636.     | base_class_visibility_list PRIVATE
  1637.         { if ($1 == (tree)visibility_public)
  1638.             error ("base class cannot be private and public");
  1639.           else if ($1 == (tree)visibility_default_virtual)
  1640.             $$ = (tree)visibility_private_virtual; }
  1641.     | base_class_visibility_list SCSPEC
  1642.         { if ($2 != ridpointers[(int)RID_VIRTUAL])
  1643.             sorry ("non-virtual visibility");
  1644.           if ($1 == (tree)visibility_public)
  1645.             $$ = (tree)visibility_public_virtual;
  1646.           else if ($1 == (tree)visibility_private)
  1647.             $$ = (tree)visibility_private_virtual; }
  1648.     ;
  1649.  
  1650. LC: '{'
  1651.         { int temp = allocation_temporary_p ();
  1652.           int momentary = suspend_momentary ();
  1653.           if (temp)
  1654.             end_temporary_allocation ();
  1655.           $$ = (momentary << 1) | temp;
  1656.           if (! IS_AGGR_TYPE ($<ttype>0))
  1657.             {
  1658.               $<ttype>0 = make_lang_type (RECORD_TYPE);
  1659.               TYPE_NAME ($<ttype>0) = get_identifier ("erroneous type");
  1660.             }
  1661.           pushclass ($<ttype>0, 0); }
  1662.  
  1663. opt.component_decl_list:
  1664.     /* empty */
  1665.         { $$ = NULL_TREE; }
  1666.     | component_decl_list
  1667.         { $$ = build_tree_list ((tree)visibility_default, $1); }
  1668.     | opt.component_decl_list PUBLIC ':' component_decl_list
  1669.         { $$ = chainon ($1, build_tree_list ((tree)visibility_public, $4)); }
  1670.     | opt.component_decl_list PRIVATE ':' component_decl_list
  1671.         { $$ = chainon ($1, build_tree_list ((tree)visibility_private, $4)); }
  1672.     | opt.component_decl_list PROTECTED ':' component_decl_list
  1673.         { $$ = chainon ($1, build_tree_list ((tree)visibility_protected, $4)); }
  1674.     | opt.component_decl_list PUBLIC ':'
  1675.     | opt.component_decl_list PRIVATE ':'
  1676.     | opt.component_decl_list PROTECTED ':'
  1677.     ;
  1678.  
  1679. component_decl_list:
  1680.       component_decl
  1681.         { if ($1 == void_type_node) $$ = NULL_TREE; }
  1682.     | component_decl_list component_decl
  1683.         { if ($2 != NULL_TREE && $2 != void_type_node)
  1684.             $$ = chainon ($1, $2); }
  1685.     | component_decl_list ';'
  1686.         { if (pedantic)
  1687.             warning ("extra semicolon in struct or union specified"); }
  1688.     ;
  1689.  
  1690. component_decl:
  1691.       typed_declspecs components ';'
  1692.         {
  1693.         do_components:
  1694.           if ($2 == void_type_node)
  1695.             /* We just got some friends.
  1696.                They have been recorded elsewhere.  */
  1697.             $$ = NULL_TREE;
  1698.           else if ($2 == NULL_TREE)
  1699.             {
  1700.               tree t = groktypename (build_decl_list ($1, NULL_TREE));
  1701.               if (t == NULL_TREE)
  1702.             {
  1703.               error ("error in component specification");
  1704.               $$ = NULL_TREE;
  1705.             }
  1706.               else if (TREE_CODE (t) == UNION_TYPE)
  1707.             {
  1708.               /* handle anonymous unions */
  1709.               if (CLASSTYPE_METHOD_VEC (t))
  1710.                 sorry ("methods in anonymous unions");
  1711.               $$ = build_lang_field_decl (FIELD_DECL, NULL_TREE, t);
  1712.               DECL_ANON_UNION_ELEM ($$) = 1;
  1713.             }
  1714.               else if (TREE_CODE (t) == ENUMERAL_TYPE)
  1715.             $$ = grok_enum_decls (t, NULL_TREE);
  1716.               else if (TREE_CODE (t) == RECORD_TYPE)
  1717.             {
  1718.               if (TYPE_LANG_SPECIFIC (t)
  1719.                   && CLASSTYPE_DECLARED_EXCEPTION (t))
  1720.                 shadow_tag ($1);
  1721.               $$ = NULL_TREE;
  1722.             }
  1723.               else if (t != void_type_node)
  1724.             {
  1725.               error ("empty component declaration");
  1726.               $$ = NULL_TREE;
  1727.             }
  1728.               else $$ = NULL_TREE;
  1729.             }
  1730.           else
  1731.             {
  1732.               tree t = TREE_TYPE ($2);
  1733.               if (TREE_CODE (t) == ENUMERAL_TYPE && TREE_NONLOCAL (t))
  1734.             $$ = grok_enum_decls (t, $2);
  1735.               else
  1736.             $$ = $2;
  1737.             }
  1738.           end_exception_decls ();
  1739.         }
  1740.     | typed_declspecs '(' parmlist ')' ';'
  1741.         { $$ = groktypefield ($1, $3); }
  1742.     | typed_declspecs '(' parmlist ')' '}'
  1743.         { error ("missing ';' before right brace");
  1744.           yyungetc ('}', 0);
  1745.           $$ = groktypefield ($1, $3); }
  1746.     | typed_declspecs LEFT_RIGHT ';'
  1747.         { $$ = groktypefield ($1, empty_parms ()); }
  1748.     | typed_declspecs LEFT_RIGHT '}'
  1749.         { error ("missing ';' before right brace");
  1750.           yyungetc ('}', 0);
  1751.           $$ = groktypefield ($1, empty_parms ()); }
  1752.     | declmods components ';'
  1753.         { goto do_components; }
  1754.     /* Normal case: make this fast.  */
  1755.     | declmods declarator ';'
  1756.         { $$ = grokfield ($2, $1, 0, 0, 0, 0); }
  1757.     | declmods components '}'
  1758.         { error ("missing ';' before right brace");
  1759.           yyungetc ('}', 0);
  1760.           goto do_components; }
  1761.     | declmods '(' parmlist ')' ';'
  1762.         { $$ = groktypefield ($1, $3); }
  1763.     | declmods '(' parmlist ')' '}'
  1764.         { error ("missing ';' before right brace");
  1765.           yyungetc ('}', 0);
  1766.           $$ = groktypefield ($1, $3); }
  1767.     | declmods LEFT_RIGHT ';'
  1768.         { $$ = groktypefield ($1, empty_parms ()); }
  1769.     | declmods LEFT_RIGHT '}'
  1770.         { error ("missing ';' before right brace");
  1771.           yyungetc ('}', 0);
  1772.           $$ = groktypefield ($1, empty_parms ()); }
  1773.     | ':' expr_no_commas ';'
  1774.         { $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); }
  1775.     | ':' expr_no_commas '}'
  1776.         { error ("missing ';' before right brace");
  1777.           yyungetc ('}', 0);
  1778.           $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); }
  1779.     | error
  1780.         { $$ = NULL_TREE; }
  1781.  
  1782.     /* C++: handle constructors, destructors and inline functions */
  1783.     /* note that INLINE is like a TYPESPEC */
  1784.     | fn.def2 ':' /* base_init compstmt */
  1785.         { $$ = finish_method ($1); }
  1786.     | fn.def2 '{' /* nodecls compstmt */
  1787.         { $$ = finish_method ($1); }
  1788.     | dummy_decl notype_declarator maybe_raises ';'
  1789.         { $$ = grokfield ($2, NULL_TREE, $3, NULL_TREE, NULL_TREE); }
  1790.     | dummy_decl notype_declarator maybe_raises '}'
  1791.         { error ("missing ';' before right brace");
  1792.           yyungetc ('}', 0);
  1793.           $$ = grokfield ($2, NULL_TREE, $3, NULL_TREE, NULL_TREE); }
  1794.     ;
  1795.  
  1796. components:
  1797.       /* empty: possibly anonymous */
  1798.         { $$ = NULL_TREE; }
  1799.     | component_declarator0
  1800.     | components ',' component_declarator
  1801.         {
  1802.           /* In this context, void_type_node encodes
  1803.              friends.  They have been recorded elsewhere.  */
  1804.           if ($1 == void_type_node)
  1805.             $$ = $3;
  1806.           else
  1807.             $$ = chainon ($1, $3);
  1808.         }
  1809.     ;
  1810.  
  1811. component_declarator0:
  1812.       declarator maybe_raises maybeasm opt.init
  1813.         { current_declspecs = $<ttype>0;
  1814.           $$ = grokfield ($1, current_declspecs, $2, $4, $3); }
  1815.     | IDENTIFIER ':' expr_no_commas
  1816.         { current_declspecs = $<ttype>0;
  1817.           $$ = grokbitfield ($1, current_declspecs, $3); }
  1818.     | TYPENAME_COLON expr_no_commas
  1819.         { current_declspecs = $<ttype>0;
  1820.           $$ = grokbitfield ($1, current_declspecs, $2); }
  1821.     | ':' expr_no_commas
  1822.         { current_declspecs = $<ttype>0;
  1823.           $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); }
  1824.     ;
  1825.  
  1826. component_declarator:
  1827.       declarator maybe_raises maybeasm opt.init
  1828.         { $$ = grokfield ($1, current_declspecs, $2, $4, $3); }
  1829.     | IDENTIFIER ':' expr_no_commas
  1830.         { $$ = grokbitfield ($1, current_declspecs, $3); }
  1831.     | TYPENAME_COLON expr_no_commas
  1832.         { $$ = grokbitfield ($1, current_declspecs, $2); }
  1833.     | ':' expr_no_commas
  1834.         { $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); }
  1835.     ;
  1836.  
  1837. /* We chain the enumerators in reverse order.
  1838.    Because of the way enums are built, the order is
  1839.    insignificant.  Take advantage of this fact.  */
  1840.  
  1841. enumlist:
  1842.       enumerator
  1843.     | enumlist ',' enumerator
  1844.         { TREE_CHAIN ($3) = $1; $$ = $3; }
  1845.     ;
  1846.  
  1847. enumerator:
  1848.       identifier
  1849.         { $$ = build_enumerator ($1, NULL_TREE); }
  1850.     | identifier '=' expr_no_commas
  1851.         { $$ = build_enumerator ($1, $3); }
  1852.     ;
  1853.  
  1854. typename:
  1855.       typed_typespecs absdcl
  1856.         { $$ = build_decl_list ($1, $2); }
  1857.     | nonempty_type_quals absdcl
  1858.         { $$ = build_decl_list ($1, $2); }
  1859.     ;
  1860.  
  1861. absdcl:   /* an abstract declarator */
  1862.     /* empty */ %prec EMPTY
  1863.         { $$ = NULL_TREE; }
  1864.     | absdcl1  %prec EMPTY
  1865.     ;
  1866.  
  1867. nonempty_type_quals:
  1868.       dummy_decl TYPE_QUAL
  1869.         { $$ = IDENTIFIER_AS_LIST ($2); }
  1870.     | nonempty_type_quals TYPE_QUAL
  1871.         { $$ = decl_tree_cons (NULL_TREE, $2, $1); }
  1872.     ;
  1873.  
  1874. type_quals:
  1875.       /* empty */
  1876.         { $$ = NULL_TREE; }
  1877.     | type_quals TYPE_QUAL
  1878.         { $$ = decl_tree_cons (NULL_TREE, $2, $1); }
  1879.     ;
  1880.  
  1881. /* These rules must follow the rules for function declarations
  1882.    and component declarations.  That way, longer rules are prefered.  */
  1883.  
  1884. /* An expression which will not live on the momentary obstack.  */
  1885. nonmomentary_expr:
  1886.     { $<itype>$ = suspend_momentary (); } expr
  1887.     { resume_momentary ($<itype>1); $$ = $2; }
  1888.  
  1889. /* A declarator that is allowed only after an explicit typespec.  */
  1890. /* may all be followed by prec '.' */
  1891. after_type_declarator:
  1892.       after_type_declarator '(' nonnull_exprlist ')' type_quals  %prec '.'
  1893.         { $$ = build_parse_node (CALL_EXPR, $1, $3, $5); }
  1894.     | after_type_declarator '(' parmlist ')' type_quals  %prec '.'
  1895.         { $$ = build_parse_node (CALL_EXPR, $1, $3, $5); }
  1896.     | after_type_declarator LEFT_RIGHT type_quals  %prec '.'
  1897.         { $$ = build_parse_node (CALL_EXPR, $1, empty_parms (), $3); }
  1898.     | after_type_declarator '(' error ')' type_quals  %prec '.'
  1899.         { $$ = build_parse_node (CALL_EXPR, $1, NULL_TREE, NULL_TREE); }
  1900.     | after_type_declarator '[' nonmomentary_expr ']'
  1901.         { $$ = build_parse_node (ARRAY_REF, $1, $3); }
  1902.     | after_type_declarator '[' ']'
  1903.         { $$ = build_parse_node (ARRAY_REF, $1, NULL_TREE); }
  1904.     | '(' dummy_decl after_type_declarator_no_typename ')'
  1905.         { $$ = $3; }
  1906.     | '(' '*' type_quals after_type_declarator ')'
  1907.         { $$ = make_pointer_declarator ($3, $4); }
  1908.     | PAREN_STAR_PAREN
  1909.         { $$ = $1;
  1910.           see_typename (); }
  1911.     | PAREN_X_SCOPE_STAR_PAREN
  1912.         { $$ = $1;
  1913.           see_typename (); }
  1914.     | PAREN_X_SCOPE_REF_PAREN
  1915.         { $$ = $1;
  1916.           see_typename (); }
  1917.     | '(' '&' type_quals after_type_declarator ')'
  1918.         { $$ = make_reference_declarator ($3, $4); }
  1919.     | '*' type_quals after_type_declarator  %prec UNARY
  1920.         { $$ = make_pointer_declarator ($2, $3); }
  1921.     | '&' type_quals after_type_declarator  %prec UNARY
  1922.         { $$ = make_reference_declarator ($2, $3); }
  1923.     | TYPENAME
  1924.     ;
  1925.  
  1926. after_type_declarator_no_typename:
  1927.       after_type_declarator_no_typename '(' nonnull_exprlist ')' type_quals  %prec '.'
  1928.         { $$ = build_parse_node (CALL_EXPR, $1, $3, $5); }
  1929.     | after_type_declarator_no_typename '(' parmlist ')' type_quals  %prec '.'
  1930.         { $$ = build_parse_node (CALL_EXPR, $1, $3, $5); }
  1931.     | after_type_declarator_no_typename LEFT_RIGHT type_quals  %prec '.'
  1932.         { $$ = build_parse_node (CALL_EXPR, $1, empty_parms (), $3); }
  1933.     | after_type_declarator_no_typename '(' error ')' type_quals  %prec '.'
  1934.         { $$ = build_parse_node (CALL_EXPR, $1, NULL_TREE, NULL_TREE); }
  1935.     | after_type_declarator_no_typename '[' nonmomentary_expr ']'
  1936.         { $$ = build_parse_node (ARRAY_REF, $1, $3); }
  1937.     | after_type_declarator_no_typename '[' ']'
  1938.         { $$ = build_parse_node (ARRAY_REF, $1, NULL_TREE); }
  1939.     | '(' dummy_decl after_type_declarator_no_typename ')'
  1940.         { $$ = $3; }
  1941.     | PAREN_STAR_PAREN
  1942.         { $$ = $1;
  1943.           see_typename (); }
  1944.     | PAREN_X_SCOPE_STAR_PAREN
  1945.         { $$ = $1;
  1946.           see_typename (); }
  1947.     | PAREN_X_SCOPE_REF_PAREN
  1948.         { $$ = $1;
  1949.           see_typename (); }
  1950.     | '*' type_quals after_type_declarator  %prec UNARY
  1951.         { $$ = make_pointer_declarator ($2, $3); }
  1952.     | '&' type_quals after_type_declarator  %prec UNARY
  1953.         { $$ = make_reference_declarator ($2, $3); }
  1954.     ;
  1955.  
  1956. /* A declarator allowed whether or not there has been
  1957.    an explicit typespec.  These cannot redeclare a typedef-name.  */
  1958.  
  1959. notype_declarator:
  1960.       notype_declarator '(' nonnull_exprlist ')' type_quals  %prec '.'
  1961.         { $$ = build_parse_node (CALL_EXPR, $1, $3, $5); }
  1962.     | notype_declarator '(' parmlist ')' type_quals  %prec '.'
  1963.         { $$ = build_parse_node (CALL_EXPR, $1, $3, $5); }
  1964.     | notype_declarator LEFT_RIGHT type_quals  %prec '.'
  1965.         { $$ = build_parse_node (CALL_EXPR, $1, empty_parms (), $3); }
  1966.     | notype_declarator '(' error ')' type_quals  %prec '.'
  1967.         { $$ = build_parse_node (CALL_EXPR, $1, NULL_TREE, NULL_TREE); }
  1968.     | '(' notype_declarator ')'
  1969.         { $$ = $2; }
  1970.     | '*' type_quals notype_declarator  %prec UNARY
  1971.         { $$ = make_pointer_declarator ($2, $3); }
  1972.     | '&' type_quals notype_declarator  %prec UNARY
  1973.         { $$ = make_reference_declarator ($2, $3); }
  1974.     | notype_declarator '[' nonmomentary_expr ']'
  1975.         { $$ = build_parse_node (ARRAY_REF, $1, $3); }
  1976.     | notype_declarator '[' ']'
  1977.         { $$ = build_parse_node (ARRAY_REF, $1, NULL_TREE); }
  1978.     | IDENTIFIER
  1979.         { see_typename (); }
  1980.  
  1981.     /* C++ extensions.  */
  1982.     | operator_name
  1983.         { see_typename (); }
  1984.  
  1985.     | '~' TYPENAME
  1986.         { see_typename ();
  1987.           $$ = build_parse_node (BIT_NOT_EXPR, $2); }
  1988.     | '~' IDENTIFIER
  1989.         { see_typename ();
  1990.           $$ = build_parse_node (BIT_NOT_EXPR, $2); }
  1991.     | LEFT_RIGHT identifier
  1992.         {
  1993.           see_typename ();
  1994.           $$ = build_parse_node (WRAPPER_EXPR, $2);
  1995.         }
  1996.     | LEFT_RIGHT '?' identifier
  1997.         {
  1998.           see_typename ();
  1999.           $$ = build_parse_node (WRAPPER_EXPR,
  2000.                  build_parse_node (COND_EXPR, $3, NULL_TREE, NULL_TREE));
  2001.         }
  2002.     | '~' LEFT_RIGHT identifier
  2003.         { see_typename ();
  2004.           $$ = build_parse_node (ANTI_WRAPPER_EXPR, $3); }
  2005.     | TYPENAME_SCOPE type_quals notype_declarator  %prec '('
  2006.         { see_typename ();
  2007.           $$ = build_parse_node (SCOPE_REF, $1, $3); }
  2008.     | TYPENAME_SCOPE TYPENAME  %prec '('
  2009.         { $$ = build_parse_node (SCOPE_REF, $1, $2); }
  2010.     | TYPENAME_SCOPE see_typename TYPENAME '(' nonnull_exprlist ')' type_quals  %prec '.'
  2011.         { $$ = build_parse_node (SCOPE_REF, $1,
  2012.                  build_parse_node (CALL_EXPR, $3, $5, $7)); }
  2013.     | TYPENAME_SCOPE see_typename TYPENAME '(' parmlist ')' type_quals  %prec '.'
  2014.         { $$ = build_parse_node (SCOPE_REF, $1,
  2015.                  build_parse_node (CALL_EXPR, $3, $5, $7)); }
  2016.     | TYPENAME_SCOPE see_typename TYPENAME LEFT_RIGHT type_quals  %prec '.'
  2017.         { $$ = build_parse_node (SCOPE_REF, $1,
  2018.                  build_parse_node (CALL_EXPR, $3, empty_parms (), $5)); }
  2019.     | TYPENAME_SCOPE see_typename TYPENAME '(' error ')' type_quals  %prec '.'
  2020.         { $$ = build_parse_node (SCOPE_REF, $1, build_parse_node (CALL_EXPR, $3, NULL_TREE, NULL_TREE)); }
  2021.     | SCOPE see_typename notype_declarator
  2022.         { $$ = build_parse_node (SCOPE_REF, NULL_TREE, $3); }
  2023.     ;
  2024.  
  2025. scoped_identifier:
  2026.       TYPENAME_SCOPE
  2027.     | IDENTIFIER SCOPE
  2028.     | scoped_identifier TYPENAME_SCOPE
  2029.         { $$ = build_parse_node (SCOPE_REF, $1, $2); }
  2030.     ;
  2031.  
  2032. absdcl1:  /* a nonempty abstract declarator */
  2033.       '(' absdcl1 ')'
  2034.         { see_typename ();
  2035.           $$ = $2; }
  2036.       /* `(typedef)1' is `int'.  */
  2037.     | '*' type_quals absdcl1  %prec EMPTY
  2038.         { $$ = make_pointer_declarator ($2, $3); }
  2039.     | '*' type_quals  %prec EMPTY
  2040.         { $$ = make_pointer_declarator ($2, NULL_TREE); }
  2041.     | PAREN_STAR_PAREN
  2042.         { $$ = $1;
  2043.           see_typename (); }
  2044.     | PAREN_X_SCOPE_STAR_PAREN
  2045.         { $$ = $1;
  2046.           see_typename (); }
  2047.     | PAREN_X_SCOPE_REF_PAREN
  2048.         { $$ = $1;
  2049.           see_typename (); }
  2050.     | '&' type_quals absdcl1 %prec EMPTY
  2051.         { $$ = make_reference_declarator ($2, $3); }
  2052.     | '&' type_quals %prec EMPTY
  2053.         { $$ = make_reference_declarator ($2, NULL_TREE); }
  2054.     | absdcl1 '(' parmlist ')' type_quals  %prec '.'
  2055.         { $$ = build_parse_node (CALL_EXPR, $1, $3, $5); }
  2056.     | absdcl1 LEFT_RIGHT type_quals  %prec '.'
  2057.         { $$ = build_parse_node (CALL_EXPR, $1, empty_parms (), $3); }
  2058.     | absdcl1 '[' nonmomentary_expr ']'  %prec '.'
  2059.         { $$ = build_parse_node (ARRAY_REF, $1, $3); }
  2060.     | absdcl1 '[' ']'  %prec '.'
  2061.         { $$ = build_parse_node (ARRAY_REF, $1, NULL_TREE); }
  2062.     | '(' parmlist ')' type_quals  %prec '.'
  2063.         { $$ = build_parse_node (CALL_EXPR, NULL_TREE, $2, $4); }
  2064.     | LEFT_RIGHT type_quals  %prec '.'
  2065.         { $$ = build_parse_node (CALL_EXPR, NULL_TREE, empty_parms (), $2); }
  2066.     | '[' nonmomentary_expr ']'  %prec '.'
  2067.         { $$ = build_parse_node (ARRAY_REF, NULL_TREE, $2); }
  2068.     | '[' ']'  %prec '.'
  2069.         { $$ = build_parse_node (ARRAY_REF, NULL_TREE, NULL_TREE); }
  2070.     | TYPENAME_SCOPE type_quals absdcl1  %prec EMPTY
  2071.         { $$ = build_parse_node (SCOPE_REF, $1, $3); }
  2072.     | IDENTIFIER SCOPE type_quals absdcl1  %prec EMPTY
  2073.         { $$ = build_parse_node (SCOPE_REF, $1, $4); }
  2074.     | TYPENAME_SCOPE type_quals %prec EMPTY
  2075.         { $$ = build_parse_node (SCOPE_REF, $1, 0); }
  2076.     | IDENTIFIER SCOPE type_quals %prec EMPTY
  2077.         { $$ = build_parse_node (SCOPE_REF, $1, 0); }
  2078.     ;
  2079.  
  2080. /* For C++, decls and stmts can be intermixed, so we don't need to
  2081.    have a special rule that won't start parsing the stmt section
  2082.    until we have a stmt that parses without errors.  */
  2083.  
  2084. stmts:
  2085.       stmt
  2086.     | errstmt
  2087.     | stmts stmt
  2088.     | stmts errstmt
  2089.     ;
  2090.  
  2091. errstmt:  error ';'
  2092.     ;
  2093.  
  2094. /* build the LET_STMT node before parsing its contents,
  2095.   so that any LET_STMTs within the context can have their display pointers
  2096.   set up to point at this one.  */
  2097.  
  2098. .pushlevel:  /* empty */
  2099.         {
  2100.           pushlevel (0);
  2101.           clear_last_expr ();
  2102.           push_momentary ();
  2103.           expand_start_bindings (0);
  2104.           stmt_decl_msg = 0;
  2105.         }
  2106.     ;
  2107.  
  2108. /* This is the body of a function definition.
  2109.    It causes syntax errors to ignore to the next openbrace.  */
  2110. compstmt_or_error:
  2111.       compstmt
  2112.         {}
  2113.     | error compstmt
  2114.     ;
  2115.  
  2116. compstmt: '{' '}'
  2117.         { $$ = 0; }
  2118.     | '{' .pushlevel stmts '}'
  2119.         { tree decls;
  2120.  
  2121.           pop_implicit_try_blocks (NULL_TREE);
  2122.           decls = getdecls ();
  2123.           expand_end_bindings (decls, decls != 0, 1);
  2124.           $$ = poplevel (decls != 0, 1, 0);
  2125.           pop_momentary (); }
  2126.     | '{' .pushlevel error '}'
  2127.         { pop_implicit_try_blocks (NULL_TREE);
  2128.           expand_end_bindings (getdecls (), 0, 1);
  2129.           $$ = poplevel (0, 0, 0);
  2130.           pop_momentary (); }
  2131.     ;
  2132.  
  2133. simple_if:
  2134.       IF '(' expr ')'
  2135.         { emit_line_note (input_filename, lineno);
  2136.           expand_start_cond (truthvalue_conversion ($3), 0);
  2137.           stmt_decl_msg = "if"; }
  2138.       stmt
  2139.         { stmt_decl_msg = 0; }
  2140.     ;
  2141.  
  2142. stmt:
  2143.       compstmt
  2144.         { finish_stmt (); }
  2145.     | decl
  2146.         { if (stmt_decl_msg)
  2147.             error ("declaration after %s invalid", stmt_decl_msg);
  2148.           stmt_decl_msg = 0;
  2149.           finish_stmt (); }
  2150.     | expr ';'
  2151.         { emit_line_note (input_filename, lineno);
  2152.           /* Do default conversion if safe and possibly important,
  2153.              in case within ({...}).  */
  2154.           if ((TREE_CODE (TREE_TYPE ($1)) == ARRAY_TYPE
  2155.                && lvalue_p ($1))
  2156.               || TREE_CODE (TREE_TYPE ($1)) == FUNCTION_TYPE)
  2157.             $1 = default_conversion ($1);
  2158.           cplus_expand_expr_stmt ($1);
  2159.           clear_momentary ();
  2160.           finish_stmt (); }
  2161.     | simple_if ELSE
  2162.         { expand_start_else ();
  2163.           stmt_decl_msg = "else"; }
  2164.       stmt
  2165.         { expand_end_else ();
  2166.           stmt_decl_msg = 0;
  2167.           finish_stmt (); }
  2168.     | simple_if %prec IF
  2169.         { expand_end_cond ();
  2170.           stmt_decl_msg = 0;
  2171.           finish_stmt (); }
  2172.     | WHILE
  2173.         { emit_nop ();
  2174.           emit_line_note (input_filename, lineno);
  2175.           expand_start_loop (1); }
  2176.       '(' expr ')'
  2177.         { expand_exit_loop_if_false (truthvalue_conversion ($4));
  2178.           stmt_decl_msg = "while"; }
  2179.       stmt
  2180.         { 
  2181.           expand_end_loop ();
  2182.           stmt_decl_msg = 0;
  2183.           finish_stmt (); }
  2184.     | DO
  2185.         { emit_nop ();
  2186.           emit_line_note (input_filename, lineno);
  2187.           expand_start_loop_continue_elsewhere (1);
  2188.           stmt_decl_msg = "do"; }
  2189.       stmt WHILE
  2190.         { stmt_decl_msg = 0;
  2191.           expand_loop_continue_here (); }
  2192.       '(' expr ')' ';'
  2193.         { emit_line_note (input_filename, lineno);
  2194.           expand_exit_loop_if_false (truthvalue_conversion ($7));
  2195.           expand_end_loop ();
  2196.           clear_momentary ();
  2197.           finish_stmt (); }
  2198.     | forhead.1
  2199.         { emit_nop ();
  2200.           emit_line_note (input_filename, lineno);
  2201.           if ($1) cplus_expand_expr_stmt ($1);
  2202.           expand_start_loop_continue_elsewhere (1); }
  2203.       xexpr ';'
  2204.         { emit_line_note (input_filename, lineno);
  2205.           if ($3) expand_exit_loop_if_false (truthvalue_conversion ($3)); }
  2206.       xexpr ')'
  2207.         /* Don't let the tree nodes for $6 be discarded
  2208.            by clear_momentary during the parsing of the next stmt.  */
  2209.         { push_momentary ();
  2210.           stmt_decl_msg = "for"; }
  2211.       stmt
  2212.         { emit_line_note (input_filename, lineno);
  2213.           expand_loop_continue_here ();
  2214.           if ($6) cplus_expand_expr_stmt ($6);
  2215.           pop_momentary ();
  2216.           expand_end_loop ();
  2217.           stmt_decl_msg = 0;
  2218.           finish_stmt (); }
  2219.     | forhead.2
  2220.         { emit_nop ();
  2221.           emit_line_note (input_filename, lineno);
  2222.           expand_start_loop_continue_elsewhere (1); }
  2223.       xexpr ';'
  2224.         { emit_line_note (input_filename, lineno);
  2225.           if ($3) expand_exit_loop_if_false (truthvalue_conversion ($3)); }
  2226.       xexpr ')'
  2227.         /* Don't let the tree nodes for $6 be discarded
  2228.            by clear_momentary during the parsing of the next stmt.  */
  2229.         { push_momentary ();
  2230.           stmt_decl_msg = "for";
  2231.           $<itype>7 = lineno; }
  2232.       stmt
  2233.         { emit_line_note (input_filename, $<itype>7);
  2234.           expand_loop_continue_here ();
  2235.           if ($6) cplus_expand_expr_stmt ($6);
  2236.           pop_momentary ();
  2237.           expand_end_loop ();
  2238.           pop_implicit_try_blocks (NULL_TREE);
  2239.           if ($1)
  2240.             {
  2241.               register keep = $1 > 0;
  2242.               if (keep) expand_end_bindings (0, keep, 1);
  2243.               poplevel (keep, 1, 0);
  2244.               pop_momentary ();
  2245.             }
  2246.           stmt_decl_msg = 0;
  2247.           finish_stmt ();
  2248.         }
  2249.     | SWITCH '(' expr ')'
  2250.         { emit_line_note (input_filename, lineno);
  2251.           c_expand_start_case ($3);
  2252.           /* Don't let the tree nodes for $3 be discarded by
  2253.              clear_momentary during the parsing of the next stmt.  */
  2254.           push_momentary ();
  2255.           stmt_decl_msg = "switch"; }
  2256.       stmt
  2257.         { expand_end_case ($3);
  2258.           pop_momentary ();
  2259.           stmt_decl_msg = 0;
  2260.           finish_stmt (); }
  2261.     | CASE expr ':'
  2262.         { register tree value = $2;
  2263.           register tree label
  2264.             = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
  2265.  
  2266.           /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
  2267.              Strip such NOP_EXPRs.  */
  2268.           if (TREE_CODE (value) == NOP_EXPR
  2269.               && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
  2270.             value = TREE_OPERAND (value, 0);
  2271.  
  2272.           if (TREE_READONLY_DECL_P (value))
  2273.             {
  2274.               value = decl_constant_value (value);
  2275.               /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
  2276.              Strip such NOP_EXPRs.  */
  2277.               if (TREE_CODE (value) == NOP_EXPR
  2278.               && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
  2279.             value = TREE_OPERAND (value, 0);
  2280.             }
  2281.           value = fold (value);
  2282.  
  2283.           if (TREE_CODE (value) != INTEGER_CST
  2284.               && value != error_mark_node)
  2285.             {
  2286.               error ("case label does not reduce to an integer constant");
  2287.               value = error_mark_node;
  2288.             }
  2289.           else
  2290.             /* Promote char or short to int.  */
  2291.             value = default_conversion (value);
  2292.           if (value != error_mark_node)
  2293.             {
  2294.               int success = pushcase (value, label);
  2295.               if (success == 1)
  2296.             error ("case label not within a switch statement");
  2297.               else if (success == 2)
  2298.             error ("duplicate case value");
  2299.               else if (success == 3)
  2300.             warning ("case value out of range");
  2301.             }
  2302.           define_case_label (label);
  2303.         }
  2304.       stmt
  2305.     | CASE expr RANGE expr ':'
  2306.         { register tree value1 = $2;
  2307.           register tree value2 = $4;
  2308.           register tree label
  2309.             = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
  2310.  
  2311.           if (pedantic)
  2312.             {
  2313.               error ("ANSI C does not allow range expressions in switch statement");
  2314.               value1 = error_mark_node;
  2315.               value2 = error_mark_node;
  2316.               break;
  2317.             }
  2318.           /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
  2319.              Strip such NOP_EXPRs.  */
  2320.           if (TREE_CODE (value1) == NOP_EXPR
  2321.               && TREE_TYPE (value1) == TREE_TYPE (TREE_OPERAND (value1, 0)))
  2322.             value1 = TREE_OPERAND (value1, 0);
  2323.  
  2324.           if (TREE_READONLY_DECL_P (value1))
  2325.             {
  2326.               value1 = decl_constant_value (value1);
  2327.               /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
  2328.              Strip such NOP_EXPRs.  */
  2329.               if (TREE_CODE (value1) == NOP_EXPR
  2330.               && TREE_TYPE (value1) == TREE_TYPE (TREE_OPERAND (value1, 0)))
  2331.             value1 = TREE_OPERAND (value1, 0);
  2332.             }
  2333.           value1 = fold (value1);
  2334.  
  2335.           /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
  2336.              Strip such NOP_EXPRs.  */
  2337.           if (TREE_CODE (value2) == NOP_EXPR
  2338.               && TREE_TYPE (value2) == TREE_TYPE (TREE_OPERAND (value2, 0)))
  2339.             value2 = TREE_OPERAND (value2, 0);
  2340.  
  2341.           if (TREE_READONLY_DECL_P (value2))
  2342.             {
  2343.               value2 = decl_constant_value (value2);
  2344.               /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
  2345.              Strip such NOP_EXPRs.  */
  2346.               if (TREE_CODE (value2) == NOP_EXPR
  2347.               && TREE_TYPE (value2) == TREE_TYPE (TREE_OPERAND (value2, 0)))
  2348.             value2 = TREE_OPERAND (value2, 0);
  2349.             }
  2350.           value2 = fold (value2);
  2351.  
  2352.  
  2353.           if (TREE_CODE (value1) != INTEGER_CST
  2354.               && value1 != error_mark_node)
  2355.             {
  2356.               error ("case label does not reduce to an integer constant");
  2357.               value1 = error_mark_node;
  2358.             }
  2359.           if (TREE_CODE (value2) != INTEGER_CST
  2360.               && value2 != error_mark_node)
  2361.             {
  2362.               error ("case label does not reduce to an integer constant");
  2363.               value2 = error_mark_node;
  2364.             }
  2365.           if (value1 != error_mark_node
  2366.               && value2 != error_mark_node)
  2367.             {
  2368.               int success = pushcase_range (value1, value2, label);
  2369.               if (success == 1)
  2370.             error ("case label not within a switch statement");
  2371.               else if (success == 2)
  2372.             error ("duplicate (or overlapping) case value");
  2373.               else if (success == 3)
  2374.             warning ("case value out of range");
  2375.               else if (success == 4)
  2376.             warning ("empty range specified");
  2377.             }
  2378.           define_case_label (label);
  2379.         }
  2380.       stmt
  2381.     | DEFAULT ':'
  2382.         {
  2383.           register tree label
  2384.             = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
  2385.           int success = pushcase (NULL_TREE, label);
  2386.           if (success == 1)
  2387.             error ("default label not within a switch statement");
  2388.           else if (success == 2)
  2389.             error ("multiple default labels in one switch");
  2390.         }
  2391.       stmt
  2392.     | BREAK ';'
  2393.         { emit_line_note (input_filename, lineno);
  2394.           if ( ! expand_exit_something ())
  2395.             error ("break statement not within loop or switch"); }
  2396.     | CONTINUE ';'
  2397.         { emit_line_note (input_filename, lineno);
  2398.           if (! expand_continue_loop ())
  2399.             error ("continue statement not within a loop"); }
  2400.     | RETURN ';'
  2401.         { emit_line_note (input_filename, lineno);
  2402.           c_expand_return (NULL_TREE); }
  2403.     | RETURN expr ';'
  2404.         { emit_line_note (input_filename, lineno);
  2405.           c_expand_return ($2);
  2406.           finish_stmt ();
  2407.         }
  2408.     | ASM maybe_type_qual '(' string ')' ';'
  2409.         { if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
  2410.           emit_line_note (input_filename, lineno);
  2411.           expand_asm ($4);
  2412.           finish_stmt ();
  2413.         }
  2414.     /* This is the case with just output operands.  */
  2415.     | ASM maybe_type_qual '(' string ':' asm_operands ')' ';'
  2416.         { if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
  2417.           emit_line_note (input_filename, lineno);
  2418.           c_expand_asm_operands ($4, $6, NULL_TREE, NULL_TREE,
  2419.                      $2 == ridpointers[(int)RID_VOLATILE],
  2420.                      input_filename, lineno);
  2421.           finish_stmt ();
  2422.         }
  2423.     /* This is the case with input operands as well.  */
  2424.     | ASM maybe_type_qual '(' string ':' asm_operands ':' asm_operands ')' ';'
  2425.         { if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
  2426.           emit_line_note (input_filename, lineno);
  2427.           c_expand_asm_operands ($4, $6, $8, NULL_TREE,
  2428.                      $2 == ridpointers[(int)RID_VOLATILE],
  2429.                      input_filename, lineno);
  2430.           finish_stmt ();
  2431.         }
  2432.     /* This is the case with clobbered registers as well.  */
  2433.     | ASM maybe_type_qual '(' string ':' asm_operands ':'
  2434.         asm_operands ':' asm_clobbers ')' ';'
  2435.         { if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
  2436.           emit_line_note (input_filename, lineno);
  2437.           c_expand_asm_operands ($4, $6, $8, $10,
  2438.                      $2 == ridpointers[(int)RID_VOLATILE],
  2439.                      input_filename, lineno);
  2440.           finish_stmt ();
  2441.         }
  2442.     | GOTO identifier ';'
  2443.         { tree decl;
  2444.           emit_line_note (input_filename, lineno);
  2445.           decl = lookup_label ($2);
  2446.           TREE_USED (decl) = 1;
  2447.           expand_goto (decl); }
  2448.     | IDENTIFIER ':'
  2449.         { tree label = define_label (input_filename, lineno, $1);
  2450.           emit_nop ();
  2451.           if (label)
  2452.             expand_label (label); }
  2453.       stmt
  2454.         { finish_stmt (); }
  2455.     | TYPENAME_COLON
  2456.         { tree label = define_label (input_filename, lineno, $1);
  2457.           if (label)
  2458.             expand_label (label); }
  2459.       stmt
  2460.         { finish_stmt (); }
  2461.     | ';'
  2462.         { finish_stmt (); }
  2463.  
  2464.     /* Exception handling extentions.  */
  2465.     | RAISE raise_identifier '(' nonnull_exprlist ')' ';'
  2466.         { cplus_expand_raise ($2, $4, NULL_TREE);
  2467.           finish_stmt (); }
  2468.     | RAISE raise_identifier LEFT_RIGHT ';'
  2469.         { cplus_expand_raise ($2, NULL_TREE, NULL_TREE);
  2470.           finish_stmt (); }
  2471.     | RAISE identifier ';'
  2472.         { cplus_expand_reraise ($2);
  2473.           finish_stmt (); }
  2474.     | try EXCEPT identifier '{'
  2475.         {
  2476.           tree decl = cplus_expand_end_try ($1);
  2477.           $<ttype>2 = current_exception_type;
  2478.           $<ttype>4 = current_exception_decl;
  2479.           $<ttype>$ = current_exception_object;
  2480.           cplus_expand_start_except ($3, decl);
  2481.           pushlevel (0);
  2482.           clear_last_expr ();
  2483.           push_momentary ();
  2484.           expand_start_bindings (0);
  2485.           stmt_decl_msg = 0;
  2486.         }
  2487.       except_stmts '}'
  2488.         {
  2489.           tree decls = getdecls ();
  2490.           tree block;
  2491.           /* If there is a default exception to handle,
  2492.              handle it here.  */
  2493.           if ($6)
  2494.             {
  2495.               tree decl = build_decl (CPLUS_CATCH_DECL, NULL_TREE, 0);
  2496.  
  2497.               pushlevel (1);
  2498.               expand_start_bindings (0);
  2499.               expand_expr ($6, 0, 0, 0);
  2500.               expand_end_bindings (0, 1, 0);
  2501.               block = poplevel (1, 0, 0);
  2502.  
  2503.               /* This is a catch block.  */
  2504.               TREE_LANG_FLAG_2 (block) = 1;
  2505.               STMT_VARS (block) = decl;
  2506.             }
  2507.  
  2508.           expand_end_bindings (decls, 1, 1);
  2509.           block = poplevel (1, 1, 0);
  2510.           TREE_LANG_FLAG_3 (block) = 1;
  2511.           pop_momentary ();
  2512.           current_exception_type = $<ttype>2;
  2513.           current_exception_decl = $<ttype>4;
  2514.           current_exception_object = $<ttype>5;
  2515.           cplus_expand_end_except ($6);
  2516.         }
  2517.     | try RERAISE raise_identifiers /* ';' checked for at bottom.  */
  2518.         { tree name = get_identifier ("(compiler error)");
  2519.           tree orig_ex_type = current_exception_type;
  2520.           tree orig_ex_decl = current_exception_decl;
  2521.           tree orig_ex_obj = current_exception_object;
  2522.           tree decl = cplus_expand_end_try ($1), decls;
  2523.           tree block;
  2524.  
  2525.           /* Start hidden EXCEPT.  */
  2526.           cplus_expand_start_except (name, decl);
  2527.           pushlevel (0);
  2528.           clear_last_expr ();
  2529.           push_momentary ();
  2530.           expand_start_bindings (0);
  2531.           stmt_decl_msg = 0;
  2532.  
  2533.           /* This sets up the reraise.  */
  2534.           cplus_expand_reraise ($3);
  2535.  
  2536.           decls = getdecls ();
  2537.           expand_end_bindings (decls, 1, 1);
  2538.           block = poplevel (1, 1, 0);
  2539.           TREE_LANG_FLAG_3 (block) = 1;
  2540.           pop_momentary ();
  2541.           current_exception_type = orig_ex_type;
  2542.           current_exception_decl = orig_ex_decl;
  2543.           current_exception_object = orig_ex_obj;
  2544.           /* This will reraise for us.  */
  2545.           cplus_expand_end_except (error_mark_node);
  2546.           if (yychar == YYEMPTY)
  2547.             yychar = YYLEX;
  2548.           if (yychar != ';')
  2549.             error ("missing ';' after reraise statement");
  2550.         }
  2551.     | try  %prec EMPTY
  2552.         { yyerror ("`except' missing after `try' statement");
  2553.           /* Terminate the binding contour started by special
  2554.              code in `.pushlevel'.  Automagically pops off
  2555.              the conditional we started for `try' stmt.  */
  2556.           cplus_expand_end_try ($1);
  2557.           expand_end_bindings (0, 0, 1);
  2558.           poplevel (0, 0, 0);
  2559.           pop_momentary ();
  2560.           YYERROR; }
  2561.     ;
  2562.  
  2563. try:      TRY '{' '}'
  2564.         { $$ = 0; }
  2565.     | try_head stmts '}'
  2566.         {
  2567.           $$ = 1;
  2568.           pop_implicit_try_blocks (NULL_TREE);
  2569.         }
  2570.     | try_head error '}'
  2571.         {
  2572.           $$ = 0;
  2573.           pop_implicit_try_blocks (NULL_TREE);
  2574.         }
  2575.     ;
  2576.  
  2577. try_head: TRY '{' { cplus_expand_start_try (0); } .pushlevel
  2578.  
  2579. except_stmts:
  2580.       /* empty */
  2581.         { $$ = NULL_TREE; }
  2582.     | except_stmts raise_identifier
  2583.         {
  2584.           tree type = lookup_exception_type (current_class_type, current_class_name, $2);
  2585.           if (type == NULL_TREE)
  2586.             {
  2587.               error ("`%s' is not an exception type",
  2588.                  IDENTIFIER_POINTER (TREE_VALUE ($2)));
  2589.               current_exception_type = NULL_TREE;
  2590.               TREE_TYPE (current_exception_object) = error_mark_node;
  2591.             }
  2592.           else
  2593.             {
  2594.               current_exception_type = type;
  2595.               /* In-place union.  */
  2596.               TREE_TYPE (current_exception_object) = type;
  2597.             }
  2598.           $2 = cplus_expand_start_catch ($2);
  2599.           pushlevel (1);
  2600.           expand_start_bindings (0);
  2601.         }
  2602.       compstmt
  2603.         {
  2604.           expand_end_bindings (0, 1, 0);
  2605.           $4 = poplevel (1, 0, 0);
  2606.  
  2607.           cplus_expand_end_catch (0);
  2608.  
  2609.           /* Mark this as a catch block.  */
  2610.           TREE_LANG_FLAG_2 ($4) = 1;
  2611.           if ($2 != error_mark_node)
  2612.             {
  2613.               tree decl = build_decl (CPLUS_CATCH_DECL, DECL_NAME ($2), 0);
  2614.               DECL_RTL (decl) = DECL_RTL ($2);
  2615.               TREE_CHAIN (decl) = STMT_VARS ($4);
  2616.               STMT_VARS ($4) = decl;
  2617.             }
  2618.         }
  2619.     | except_stmts DEFAULT
  2620.         {
  2621.           if ($1)
  2622.             error ("duplicate default in exception handler");
  2623.           current_exception_type = NULL_TREE;
  2624.           /* Takes it right out of scope.  */
  2625.           TREE_TYPE (current_exception_object) = error_mark_node;
  2626.  
  2627.           if (! expand_catch_default ())
  2628.             compiler_error ("default catch botch");
  2629.  
  2630.           /* The default exception is handled as the
  2631.              last in the chain of exceptions handled.  */
  2632.           do_pending_stack_adjust ();
  2633.           start_sequence ();
  2634.           $1 = make_node (RTL_EXPR);
  2635.           TREE_TYPE ($1) = void_type_node;
  2636.         }
  2637.       compstmt
  2638.         {
  2639.           do_pending_stack_adjust ();
  2640.           if (! expand_catch (NULL_TREE))
  2641.             compiler_error ("except nesting botch");
  2642.           if (! expand_end_catch ())
  2643.             compiler_error ("except nesting botch");
  2644.           RTL_EXPR_SEQUENCE ($1) = (struct rtx_def *)get_insns ();
  2645.           if ($4)
  2646.             {
  2647.               /* Mark this block as the default catch block.  */
  2648.               TREE_LANG_FLAG_1 ($4) = 1;
  2649.               TREE_LANG_FLAG_2 ($4) = 1;
  2650.             }
  2651.           end_sequence ();
  2652.         }
  2653.     ;
  2654.  
  2655. forhead.1:
  2656.       FOR '(' ';'
  2657.         { $$ = NULL_TREE; }
  2658.     | FOR '(' expr ';'
  2659.         { $$ = $3; }
  2660.     | FOR '(' '{' '}'
  2661.         { $$ = NULL_TREE; }
  2662.     ;
  2663.  
  2664. forhead.2:
  2665.       FOR '(' decl
  2666.         { $$ = 0; }
  2667.     | FOR '(' error ';'
  2668.         { $$ = 0; }
  2669.     | FOR '(' '{' .pushlevel stmts '}'
  2670.         { $$ = 1; }
  2671.     | FOR '(' '{' .pushlevel error '}'
  2672.         { $$ = -1; }
  2673.     ;
  2674.  
  2675. /* Either a type-qualifier or nothing.  First thing in an `asm' statement.  */
  2676.  
  2677. maybe_type_qual:
  2678.     /* empty */
  2679.         { if (pedantic)
  2680.             warning ("ANSI C forbids use of `asm' keyword");
  2681.           emit_line_note (input_filename, lineno); }
  2682.     | TYPE_QUAL
  2683.         { if (pedantic)
  2684.             warning ("ANSI C forbids use of `asm' keyword");
  2685.           emit_line_note (input_filename, lineno); }
  2686.     ;
  2687.  
  2688. xexpr:
  2689.     /* empty */
  2690.         { $$ = NULL_TREE; }
  2691.     | expr
  2692.     | error
  2693.         { $$ = NULL_TREE; }
  2694.     ;
  2695.  
  2696. /* These are the operands other than the first string and colon
  2697.    in  asm ("addextend %2,%1": "=dm" (x), "0" (y), "g" (*x))  */
  2698. asm_operands: /* empty */
  2699.         { $$ = NULL_TREE; }
  2700.     | nonnull_asm_operands
  2701.     ;
  2702.  
  2703. nonnull_asm_operands:
  2704.       asm_operand
  2705.     | nonnull_asm_operands ',' asm_operand
  2706.         { $$ = chainon ($1, $3); }
  2707.     ;
  2708.  
  2709. asm_operand:
  2710.       STRING '(' expr ')'
  2711.         { $$ = build_tree_list ($1, $3); }
  2712.     ;
  2713.  
  2714. asm_clobbers:
  2715.       STRING
  2716.         { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
  2717.     | asm_clobbers ',' STRING
  2718.         { $$ = tree_cons (NULL_TREE, $3, $1); }
  2719.     ;
  2720.  
  2721. /* This is what appears inside the parens in a function declarator.
  2722.    Its value is represented in the format that grokdeclarator expects.
  2723.  
  2724.    In C++, declaring a function with no parameters
  2725.    means that that function takes *no* parameters.  */
  2726. parmlist:  /* empty */
  2727.         {
  2728.           if (strict_prototype)
  2729.             $$ = void_list_node;
  2730.           else
  2731.             $$ = NULL_TREE;
  2732.         }
  2733.     | parms
  2734.           {
  2735.           $$ = chainon ($1, void_list_node);
  2736.           TREE_PARMLIST ($$) = 1;
  2737.         }
  2738.     | parms ',' ELLIPSIS
  2739.         {
  2740.           $$ = $1;
  2741.           TREE_PARMLIST ($$) = 1;
  2742.         }
  2743.     /* C++ allows an ellipsis without a separating ',' */
  2744.     | parms ELLIPSIS
  2745.         {
  2746.           $$ = $1;
  2747.           TREE_PARMLIST ($$) = 1;
  2748.         }
  2749.     | ELLIPSIS
  2750.         {
  2751.           $$ = NULL_TREE;
  2752.         }
  2753.     | TYPENAME_ELLIPSIS
  2754.         {
  2755.           $$ = $1;
  2756.           TREE_PARMLIST ($$) = 1;
  2757.         }
  2758.     | parms TYPENAME_ELLIPSIS
  2759.         {
  2760.           $$ = $1;
  2761.           TREE_PARMLIST ($$) = 1;
  2762.         }
  2763.     | parms ':'
  2764.         {
  2765.           /* This helps us recover from really nasty
  2766.              parse errors, for example, a missing right
  2767.              parenthesis.  */
  2768.           yyerror ("possibly missing ')'");
  2769.           $$ = chainon ($1, void_list_node);
  2770.           TREE_PARMLIST ($$) = 1;
  2771.           yyungetc (':', 0);
  2772.           yychar = ')';
  2773.         }
  2774.     ;
  2775.  
  2776. /* A nonempty list of parameter declarations or type names.  */
  2777. parms:
  2778.       parm opt.init
  2779.         { $$ = build_tree_list ($2, $1); }
  2780.     | parms ',' parm opt.init
  2781.         { $$ = chainon ($1, build_tree_list ($4, $3)); }
  2782.     | parms ',' bad_parm opt.init
  2783.         { $$ = chainon ($1, build_tree_list ($4, $3)); }
  2784.     ;
  2785.  
  2786. /* A single parameter declaration or parameter type name,
  2787.    as found in a parmlist.  */
  2788. parm:
  2789.       typed_declspecs dont_see_typename notype_declarator
  2790.         { $$ = build_tree_list ($1, $3);
  2791.           see_typename (); }
  2792.     | typed_declspecs dont_see_typename absdcl
  2793.         { $$ = build_tree_list ($1, $3);
  2794.           see_typename (); }
  2795.     | declmods dont_see_typename notype_declarator
  2796.         { $$ = build_tree_list ($1, $3);
  2797.           see_typename (); }
  2798.     | declmods dont_see_typename absdcl
  2799.         { $$ = build_tree_list ($1, $3);
  2800.           see_typename (); }
  2801.     ;
  2802.  
  2803. see_typename: type_quals
  2804.     { see_typename (); }
  2805.     ;
  2806.  
  2807. dont_see_typename: /* empty */
  2808.     { dont_see_typename (); }
  2809.     ;
  2810.  
  2811. bad_parm:
  2812.       dummy_decl notype_declarator
  2813.         {
  2814.           warning ("type specifier omitted for parameter");
  2815.           $$ = build_tree_list (TREE_PURPOSE (TREE_VALUE ($<ttype>-1)), $2);
  2816.         }
  2817.     | dummy_decl absdcl
  2818.         {
  2819.           warning ("type specifier omitted for parameter");
  2820.           $$ = build_tree_list (TREE_PURPOSE (TREE_VALUE ($<ttype>-1)), $2);
  2821.         }
  2822.     ;
  2823.  
  2824.     /* C++ extension: allow for initialization */
  2825. opt.init:
  2826.       /* empty */
  2827.         { $$ = NULL_TREE; }
  2828.     | '=' init
  2829.         { $$ = $2; }
  2830.     ;
  2831.  
  2832. maybe_raises:
  2833.       /* empty */
  2834.         { $$ = NULL_TREE; }
  2835.     | RAISES raise_identifiers  %prec EMPTY
  2836.         { $$ = $2; }
  2837.     ;
  2838.  
  2839. raise_identifier:
  2840.       ALL
  2841.         { $$ = void_list_node; }
  2842.     | IDENTIFIER
  2843.         { $$ = build_decl_list (NULL_TREE, $1); }
  2844.     | TYPENAME
  2845.         { $$ = build_decl_list (NULL_TREE, $1); }
  2846.     | SCOPE IDENTIFIER
  2847.         { $$ = build_decl_list (void_type_node, $2); }
  2848.     | SCOPE TYPENAME
  2849.         { $$ = build_decl_list (void_type_node, $2); }
  2850.     | scoped_identifier IDENTIFIER
  2851.         { $$ = build_decl_list ($1, $2); }
  2852.     | scoped_identifier TYPENAME
  2853.         { $$ = build_decl_list ($1, $2); }
  2854.  
  2855. raise_identifiers:
  2856.       raise_identifier
  2857.     | raise_identifiers ',' raise_identifier
  2858.         {
  2859.             TREE_CHAIN ($3) = $1;
  2860.           $$ = $3;
  2861.         }
  2862.     ;
  2863.  
  2864. operator_name:
  2865.       OPERATOR '*'
  2866.         { $$ = build_opid (0, MULT_EXPR); }
  2867.     | OPERATOR '/'
  2868.         { $$ = build_opid (0, TRUNC_DIV_EXPR); }
  2869.     | OPERATOR '%'
  2870.         { $$ = build_opid (0, TRUNC_MOD_EXPR); }
  2871.     | OPERATOR '+'
  2872.         { $$ = build_opid (0, PLUS_EXPR); }
  2873.     | OPERATOR '-'
  2874.         { $$ = build_opid (0, MINUS_EXPR); }
  2875.     | OPERATOR '&'
  2876.         { $$ = build_opid (0, BIT_AND_EXPR); }
  2877.     | OPERATOR '|'
  2878.         { $$ = build_opid (0, BIT_IOR_EXPR); }
  2879.     | OPERATOR '^'
  2880.         { $$ = build_opid (0, BIT_XOR_EXPR); }
  2881.     | OPERATOR '~'
  2882.         { $$ = build_opid (0, BIT_NOT_EXPR); }
  2883.     | OPERATOR ','
  2884.         { $$ = build_opid (0, COMPOUND_EXPR); }
  2885.     | OPERATOR ARITHCOMPARE
  2886.         { $$ = build_opid (0, $2); }
  2887.     | OPERATOR EQCOMPARE
  2888.         { $$ = build_opid (0, $2); }
  2889.     | OPERATOR ASSIGN
  2890.         { $$ = build_opid (MODIFY_EXPR, $2); }
  2891.     | OPERATOR '='
  2892.         {
  2893.           $$ = build_opid (MODIFY_EXPR, NOP_EXPR);
  2894.           if (current_class_type)
  2895.             {
  2896.               TYPE_HAS_ASSIGNMENT (current_class_type) = 1;
  2897.               TYPE_GETS_ASSIGNMENT (current_class_type) = 1;
  2898.             }
  2899.         }
  2900.     | OPERATOR LSHIFT
  2901.         { $$ = build_opid (0, $2); }
  2902.     | OPERATOR RSHIFT
  2903.         { $$ = build_opid (0, $2); }
  2904.     | OPERATOR PLUSPLUS
  2905.         { $$ = build_opid (0, POSTINCREMENT_EXPR); }
  2906.     | OPERATOR MINUSMINUS
  2907.         { $$ = build_opid (0, PREDECREMENT_EXPR); }
  2908.     | OPERATOR ANDAND
  2909.         { $$ = build_opid (0, TRUTH_ANDIF_EXPR); }
  2910.     | OPERATOR OROR
  2911.         { $$ = build_opid (0, TRUTH_ORIF_EXPR); }
  2912.     | OPERATOR '!'
  2913.         { $$ = build_opid (0, TRUTH_NOT_EXPR); }
  2914.     | OPERATOR '?' ':'
  2915.         { $$ = build_opid (0, COND_EXPR); }
  2916.     | OPERATOR MIN_MAX
  2917.         { $$ = build_opid (0, $2); }
  2918.     | OPERATOR POINTSAT  %prec EMPTY
  2919.         { $$ = build_opid (0, COMPONENT_REF); }
  2920.     | OPERATOR POINTSAT_LEFT_RIGHT type_quals  %prec '.'
  2921.         {
  2922.           if (yychar == YYEMPTY)
  2923.             yychar = YYLEX;
  2924.           if (yychar == '(' || yychar == LEFT_RIGHT)
  2925.             {
  2926.               $$ = build_opid (0, METHOD_CALL_EXPR);
  2927.               if (current_class_type)
  2928.             {
  2929.               tree t = current_class_type;
  2930.               while (t)
  2931.                 {
  2932.                   TYPE_OVERLOADS_METHOD_CALL_EXPR (t) = 1;
  2933.                   t = TYPE_NEXT_VARIANT (t);
  2934.                 }
  2935.             }
  2936.             }
  2937.           else
  2938.             $$ = build_parse_node (CALL_EXPR, build_opid (0, COMPONENT_REF), void_list_node, $3);
  2939.         }
  2940.     | OPERATOR LEFT_RIGHT
  2941.         { $$ = build_opid (0, CALL_EXPR);
  2942.           if (current_class_type)
  2943.             {
  2944.               tree t = current_class_type;
  2945.               while (t)
  2946.             {
  2947.               TYPE_OVERLOADS_CALL_EXPR (t) = 1;
  2948.               t = TYPE_NEXT_VARIANT (t);
  2949.             }
  2950.             }
  2951.         }
  2952.     | OPERATOR '[' ']'
  2953.         { $$ = build_opid (0, ARRAY_REF);
  2954.           if (current_class_type)
  2955.             {
  2956.               tree t = current_class_type;
  2957.               while (t)
  2958.             {
  2959.               TYPE_OVERLOADS_ARRAY_REF (t) = 1;
  2960.               t = TYPE_NEXT_VARIANT (t);
  2961.             }
  2962.             }
  2963.         }
  2964.     | OPERATOR NEW
  2965.         {
  2966.           $$ = build_opid (0, NEW_EXPR);
  2967.           if (current_class_type)
  2968.             {
  2969.               tree t = current_class_type;
  2970.               while (t)
  2971.             {
  2972.               TREE_GETS_NEW (t) = 1;
  2973.               t = TYPE_NEXT_VARIANT (t);
  2974.             }
  2975.             }
  2976.         }
  2977.     | OPERATOR DELETE
  2978.         {
  2979.           $$ = build_opid (0, DELETE_EXPR);
  2980.           if (current_class_type)
  2981.             {
  2982.               tree t = current_class_type;
  2983.               while (t)
  2984.             {
  2985.               TREE_GETS_DELETE (t) = 1;
  2986.               t = TYPE_NEXT_VARIANT (t);
  2987.             }
  2988.             }
  2989.         }
  2990.  
  2991.     /* These should do `groktypename' and set up TREE_HAS_X_CONVERSION
  2992.        here, rather than doing it in class.c .  */
  2993.     | OPERATOR typed_typespecs absdcl
  2994.         {
  2995.           $$ = build1 (TYPE_EXPR, $2, $3);
  2996.         }
  2997.     | OPERATOR error
  2998.         { $$ = build_opid (ERROR_MARK, ERROR_MARK); }
  2999.     ;
  3000.  
  3001. %%
  3002.  
  3003. #if YYDEBUG != 0
  3004. db_yyerror (s, yyps, yychar)
  3005.      char *s;
  3006.      short *yyps;
  3007.      int yychar;
  3008. {
  3009.   FILE *yyout;
  3010.   char buf[1024];
  3011.   int st;
  3012.  
  3013.   yyerror (s);
  3014.   printf ("State is %d, input token number is %d.\n", *yyps, yychar);
  3015.  
  3016. #ifdef PARSE_OUTPUT
  3017.   if (*yyps < 1) fatal ("Cannot start from here");
  3018.   else if ((yyout = fopen (PARSE_OUTPUT, "r")) == NULL)
  3019.     error ("cannot open file %s", PARSE_OUTPUT);
  3020.   else
  3021.     {
  3022.       printf ("That is to say,\n\n");
  3023.       while (fgets(buf, sizeof (buf)-1, yyout))
  3024.     {
  3025.       if (buf[0] != 's') continue;
  3026.       st = atoi (buf+6);
  3027.       if (st != *yyps) continue;
  3028.       printf ("%s", buf);
  3029.       while (fgets (buf, sizeof (buf)-1, yyout))
  3030.         {
  3031.           if (buf[0] == 's') break;
  3032.           printf ("%s", buf);
  3033.         }
  3034.       break;
  3035.     }
  3036.       printf ("With the token %s\n", yytname[YYTRANSLATE (yychar)]);
  3037.       fclose (yyout);
  3038.     }
  3039. #endif
  3040. }
  3041. #endif
  3042.  
  3043. void
  3044. yyerror (string)
  3045.      char *string;
  3046. {
  3047.   extern FILE *finput;
  3048.   extern char *token_buffer;
  3049.   char buf[200];
  3050.  
  3051.   strcpy (buf, string);
  3052.  
  3053.   /* We can't print string and character constants well
  3054.      because the token_buffer contains the result of processing escapes.  */
  3055.   if (end_of_file || feof (finput))
  3056.     strcat (buf, " at end of input");
  3057.   else if (token_buffer[0] == 0)
  3058.     strcat (buf, " at null character");
  3059.   else if (token_buffer[0] == '"')
  3060.     strcat (buf, " before string constant");
  3061.   else if (token_buffer[0] == '\'')
  3062.     strcat (buf, " before character constant");
  3063.   else
  3064.     strcat (buf, " before `%s'");
  3065.  
  3066.   error (buf, token_buffer);
  3067. }
  3068.  
  3069. static int *reduce_count;
  3070. static int *token_count;
  3071.  
  3072. #define REDUCE_LENGTH (sizeof (yyr2) / sizeof (yyr2[0]))
  3073. #define TOKEN_LENGTH (256 + YYNTBASE + 1)
  3074.  
  3075. int *
  3076. init_parse ()
  3077. {
  3078. #ifdef GATHER_STATISTICS
  3079.   reduce_count = (int *)malloc (sizeof (int) * (REDUCE_LENGTH + 1));
  3080.   bzero (reduce_count, sizeof (int) * (REDUCE_LENGTH + 1));
  3081.   reduce_count += 1;
  3082.   token_count = (int *)malloc (sizeof (int) * (TOKEN_LENGTH + 1));
  3083.   bzero (token_count, sizeof (int) * (TOKEN_LENGTH + 1));
  3084.   token_count += 1;
  3085. #endif
  3086.   return token_count;
  3087. }
  3088.  
  3089. #ifdef GATHER_STATISTICS
  3090. void
  3091. yyhook (yyn)
  3092.      int yyn;
  3093. {
  3094.   reduce_count[yyn] += 1;
  3095. }
  3096. #endif
  3097.  
  3098. static int reduce_cmp (p, q)
  3099.      int *p, *q;
  3100. {
  3101.   return reduce_count[*q] - reduce_count[*p];
  3102. }
  3103.  
  3104. static int token_cmp (p, q)
  3105.      int *p, *q;
  3106. {
  3107.   return token_count[*q] - token_count[*p];
  3108. }
  3109.  
  3110. void
  3111. print_parse_statistics ()
  3112. {
  3113.   int i;
  3114.   int maxlen = REDUCE_LENGTH;
  3115.   unsigned *sorted;
  3116.   
  3117.   if (reduce_count[-1] == 0)
  3118.     return;
  3119.  
  3120.   if (TOKEN_LENGTH > REDUCE_LENGTH)
  3121.     maxlen = TOKEN_LENGTH;
  3122.   sorted = (unsigned *) alloca (sizeof (int) * maxlen);
  3123.  
  3124.   for (i = 0; i < TOKEN_LENGTH; i++)
  3125.     sorted[i] = i;
  3126.   qsort (sorted, TOKEN_LENGTH, sizeof (int), token_cmp);
  3127.   for (i = 0; i < TOKEN_LENGTH; i++)
  3128.     {
  3129.       int index = sorted[i];
  3130.       if (token_count[index] == 0)
  3131.     break;
  3132.       if (token_count[index] < token_count[-1])
  3133.     break;
  3134.       fprintf (stderr, "token %d", index);
  3135. #if YYDEBUG
  3136.       fprintf (stderr, ", `%s'", yytname[YYTRANSLATE (index)]);
  3137. #endif
  3138.       fprintf (stderr, ", count = %d\n", token_count[index]);
  3139.     }
  3140.   fprintf (stderr, "\n");
  3141.   for (i = 0; i < REDUCE_LENGTH; i++)
  3142.     sorted[i] = i;
  3143.   qsort (sorted, REDUCE_LENGTH, sizeof (int), reduce_cmp);
  3144.   for (i = 0; i < REDUCE_LENGTH; i++)
  3145.     {
  3146.       int index = sorted[i];
  3147.       if (reduce_count[index] == 0)
  3148.     break;
  3149.       if (reduce_count[index] < reduce_count[-1])
  3150.     break;
  3151.       fprintf (stderr, "rule %d", index);
  3152. #if YYDEBUG
  3153.       fprintf (stderr, ", line %d", yyrline[index]);
  3154. #endif
  3155.       fprintf (stderr, ", count = %d\n", reduce_count[index]);
  3156.     }
  3157.   fprintf (stderr, "\n");
  3158. }
  3159.